Skip to content

Commit

Permalink
Fix min/max occurrence bug in X12 to BalEDI
Browse files Browse the repository at this point in the history
  • Loading branch information
RDPerera committed Jul 5, 2024
1 parent 46d1a0f commit 39b9402
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 15 deletions.
2 changes: 1 addition & 1 deletion edi-tools-package/BalTool.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
id = "edi"

[[dependency]]
path = "resources/edi-tools-cli-2.0.0.jar"
path = "resources/edi-tools-cli-2.0.1.jar"
2 changes: 1 addition & 1 deletion edi-tools-package/Ballerina.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
org = "ballerina"
name = "editoolspackage"
version = "2.0.0"
version = "2.0.1"
authors = ["Ballerina"]
keywords = ["edi"]
license = ["Apache-2.0"]
Expand Down
2 changes: 1 addition & 1 deletion edi-tools/Ballerina.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
org = "ballerina"
name = "editools"
version = "2.0.0"
version = "2.0.1"
authors = ["Ballerina"]
keywords = ["edi"]
license = ["Apache-2.0"]
Expand Down
10 changes: 10 additions & 0 deletions edi-tools/modules/codegen/maincode_gen.bal
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public isolated function getEDINames() returns string[] {
return ${libdata.ediNames.toString()};
}
# Convert EDI string to Ballerina record.
#
# + ediText - EDI string to be converted
# + ediName - EDI type name
# + return - Ballerina record
public isolated function fromEdiString(string ediText, EDI_NAME ediName) returns anydata|error {
EdiDeserialize? ediDeserialize = ediDeserializers[ediName];
if ediDeserialize is () {
Expand All @@ -37,6 +42,11 @@ public isolated function fromEdiString(string ediText, EDI_NAME ediName) returns
return ediDeserialize(ediText);
}
# Convert Ballerina record to EDI string.
#
# + data - Ballerina record to be converted
# + ediName - EDI type name
# + return - EDI string
public isolated function toEdiString(anydata data, EDI_NAME ediName) returns string|error {
EdiSerialize? ediSerialize = ediSerializers[ediName];
if ediSerialize is () {
Expand Down
11 changes: 10 additions & 1 deletion edi-tools/modules/codegen/rest_connector_gen.bal
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ configurable int restConnectorPort = 9090;
service /${re.replaceAll(libName,"_")}Parser on new http:Listener(restConnectorPort) {
# Resource to convert EDI string to Ballerina record.
#
# + ediType - EDI type name.
# + ediData - EDI string to be converted.
# + return - Ballerina record as JSON.
isolated resource function post edis/[string ediType](@http:Payload string ediData) returns json|error {
EDI_NAME|error ediTypeName = ediType.ensureType();
if ediTypeName is error {
Expand All @@ -31,7 +36,11 @@ service /${re.replaceAll(libName,"_")}Parser on new http:Listener(restConnectorP
anydata target = check fromEdiString(ediData, ediTypeName);
return target.toJson();
}
# Resource to convert Ballerina record to EDI string.
#
# + ediType - EDI type name.
# + jsonData - Ballerina record as JSON.
# + return - EDI string.
isolated resource function post objects/[string ediType](@http:Payload json jsonData) returns string|error {
EDI_NAME|error ediTypeName = ediType.ensureType();
if ediTypeName is error {
Expand Down
21 changes: 21 additions & 0 deletions edi-tools/modules/codegen/schema_code_gen.bal
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,47 @@ public function generateCodeForSchema(json schema, string outputPath) returns er
string schemaCode = string `
import ballerina/edi;
# Convert EDI string to Ballerina ${ediSchema.name} record.
#
# + ediText - EDI string to be converted
# + return - Ballerina record
public isolated function fromEdiString(string ediText) returns ${ediSchema.name}|error {
edi:EdiSchema ediSchema = check edi:getSchema(schemaJson);
json dataJson = check edi:fromEdiString(ediText, ediSchema);
return dataJson.cloneWithType();
}
# Convert Ballerina ${ediSchema.name} record to EDI string.
#
# + data - Ballerina record to be converted
# + return - EDI string
public isolated function toEdiString(${ediSchema.name} data) returns string|error {
edi:EdiSchema ediSchema = check edi:getSchema(schemaJson);
return edi:toEdiString(data, ediSchema);
}
# Get the EDI schema.
#
# + return - EDI schema
public isolated function getSchema() returns edi:EdiSchema|error {
return edi:getSchema(schemaJson);
}
# Convert EDI string to Ballerina ${ediSchema.name} record with schema.
#
# + ediText - EDI string to be converted
# + schema - EDI schema
# + return - Ballerina record
public isolated function fromEdiStringWithSchema(string ediText, edi:EdiSchema schema) returns ${ediSchema.name}|error {
json dataJson = check edi:fromEdiString(ediText, schema);
return dataJson.cloneWithType();
}
# Convert Ballerina ${ediSchema.name} record to EDI string with schema.
#
# + data - Ballerina record to be converted
# + ediSchema - EDI schema
# + return - EDI string
public isolated function toEdiStringWithSchema(${ediSchema.name} data, edi:EdiSchema ediSchema) returns string|error {
return edi:toEdiString(data, ediSchema);
}
Expand Down
8 changes: 8 additions & 0 deletions edi-tools/modules/codegen/transformer_gen.bal
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@ function generateTransformerCode(string ediName, string mainRecordName) returns
string transformer = string `
type InternalType ${mainRecordName};
# Convert EDI string to Ballerina ${mainRecordName} record.
#
# + ediText - EDI string to be converted
# + return - Ballerina record
public isolated function transformFromEdiString(string ediText) returns anydata|error {
${mainRecordName} data = check fromEdiString(ediText);
return transformRead(data);
}
isolated function transformRead(${mainRecordName} data) returns InternalType => data;
# Convert Ballerina ${mainRecordName} record to EDI string.
#
# + content - Ballerina record to be converted
# + return - EDI string
public isolated function transformToEdiString(anydata content) returns string|error {
${mainRecordName} data = transformWrite(check content.ensureType());
return toEdiString(data);
Expand Down
25 changes: 15 additions & 10 deletions edi-tools/modules/x12xsd/x12xsd.bal
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function convertFromX12WithHeaders(string inPath) returns edi:EdiSchema|error {
return ediSchema;
}

function convertSegmentGroup(xml segmentGroup, xml x12xsd, edi:EdiSchema schema, string dirPath = "") returns edi:EdiSegGroupSchema|error {
function convertSegmentGroup(xml segmentGroup, xml x12xsd, edi:EdiSchema schema, string dirPath = "", int parentMinOccur = 0, int parentMaxOccur = 1) returns edi:EdiSegGroupSchema|error {
xml elements = segmentGroup/<xs:complexType>/<xs:sequence>/<xs:element>;
string tag = "";
do {
Expand All @@ -112,9 +112,14 @@ function convertSegmentGroup(xml segmentGroup, xml x12xsd, edi:EdiSchema schema,
return error("Segment group name not found. " + segmentGroup.toString(), e);
}
tag = getBalCompatibleName(tag);
edi:EdiSegGroupSchema segGroupSchema = {tag};
int segMinOccur = segmentGroup.minOccurs is string ? check int:fromString(check segmentGroup.minOccurs) : parentMinOccur;
int segMaxOccur = segmentGroup.maxOccurs is string ? check segmentGroup.maxOccurs == "unbounded" ? -1 : check int:fromString(check segmentGroup.maxOccurs) : parentMaxOccur;
edi:EdiSegGroupSchema segGroupSchema = {tag: tag, minOccurances: segMinOccur, maxOccurances: segMaxOccur};
foreach xml element in elements {
string ref = check element.ref;
int eleMinOccur = element.minOccurs is string ? check int:fromString(check element.minOccurs) : 0;
int eleMaxOccur = element.maxOccurs is string ? check element.maxOccurs == "unbounded" ? -1 : check int:fromString(check element.maxOccurs) : 1;

if ref.startsWith("X12_") {
schema.name = ref;
schema.tag = ref;
Expand All @@ -125,26 +130,26 @@ function convertSegmentGroup(xml segmentGroup, xml x12xsd, edi:EdiSchema schema,
}
else if ref.startsWith("Loop_") {
xml segGroupElement = check getUnitElement(ref, x12xsd);
edi:EdiSegGroupSchema childSegGroupSchema = check convertSegmentGroup(segGroupElement, x12xsd, schema);
edi:EdiSegGroupSchema childSegGroupSchema = check convertSegmentGroup(segmentGroup = segGroupElement, x12xsd = x12xsd, schema = schema, parentMaxOccur = eleMaxOccur, parentMinOccur = eleMinOccur);
segGroupSchema.segments.push(childSegGroupSchema);
} else {
if !schema.segmentDefinitions.hasKey((ref)) {
edi:EdiSegSchema segSchema = check convertSegment(ref, x12xsd);
edi:EdiSegSchema segSchema = check convertSegment(ref, eleMinOccur, eleMaxOccur, x12xsd);
schema.segmentDefinitions[ref] = segSchema;
}
edi:EdiUnitRef segRef = {ref: ref};
edi:EdiUnitRef segRef = {ref: ref, minOccurances: eleMinOccur, maxOccurances: eleMaxOccur};
segGroupSchema.segments.push(segRef);
}
}
return segGroupSchema;
}

function convertSegment(string segmentName, xml x12xsd) returns edi:EdiSegSchema|error {
function convertSegment(string segmentName, int minOccurs, int maxOccurs, xml x12xsd) returns edi:EdiSegSchema|error {
xml segElement = check getUnitElement(segmentName, x12xsd);
string:RegExp underscorePlaceholder = re `_`;
string[] nameParts = underscorePlaceholder.split(segmentName);
edi:EdiSegSchema segSchema =
{code: getBalCompatibleName(nameParts[0]), tag: getBalCompatibleName(nameParts[1])};
{code: getBalCompatibleName(nameParts[0]), tag: getBalCompatibleName(nameParts[1]), minOccurances: minOccurs, maxOccurances: maxOccurs};
segSchema.fields.push({tag: "code", required: true});
xml fieldElements = segElement/<xs:complexType>/<xs:sequence>/<xs:element>;
foreach xml fieldElement in fieldElements {
Expand All @@ -156,9 +161,9 @@ function convertSegment(string segmentName, xml x12xsd) returns edi:EdiSegSchema
}
fieldName = getBalCompatibleName(fieldName);
edi:EdiFieldSchema fieldSchema = {tag: fieldName, required: true};
string|error minOccurs = fieldElement.minOccurs;
if (minOccurs is string) {
fieldSchema.required = minOccurs != "0";
string|error fieldMinOccurs = fieldElement.minOccurs;
if (fieldMinOccurs is string) {
fieldSchema.required = fieldMinOccurs != "0";
}
if conditionalFeildsMap.length() > 0 {
string[] nameSplit = underscorePlaceholder.split(fieldName);
Expand Down
2 changes: 1 addition & 1 deletion edi-tools/tests/resources/x12xsd/004010/210.json

Large diffs are not rendered by default.

0 comments on commit 39b9402

Please sign in to comment.