Skip to content

Commit 1ee1896

Browse files
authored
Add functionality to parse both attribute and value at the same time. (#4324)
1 parent b6b6c9a commit 1ee1896

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

legend-engine-xts-xml/legend-engine-xt-xml-javaPlatformBinding-pure/src/main/resources/core_external_format_xml_java_platform_binding/legendJavaPlatformBinding/internalize.pure

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,17 @@ function <<access.private>> meta::external::format::xml::executionPlan::platform
116116

117117
Class <<access.private>> meta::external::format::xml::executionPlan::platformBinding::legendJava::internalize::PropertyCodes
118118
{
119-
elementVar : Code[1];
120-
elementInit : Code[1];
121-
attributeVar : Code[0..1];
122-
attributeInit : Code[0..1];
123-
calledMethods : meta::external::language::java::metamodel::Method[*];
124-
125-
elementDeclare() { $this.elementVar->j_declare($this.elementInit); }: Code[1];
126-
attributeDeclare() { $this.attributeVar->map(v| $v->j_declare($this.attributeInit->toOne())); }: Code[0..1];
119+
elementVar : Code[0..1];
120+
elementInit : Code[0..1];
121+
attributeVar : Code[0..1];
122+
attributeInit : Code[0..1];
123+
textContentVar : Code[0..1];
124+
textContentInit : Code[0..1];
125+
calledMethods : meta::external::language::java::metamodel::Method[*];
126+
127+
elementDeclare() { $this.elementVar->map(v| $v ->j_declare($this.elementInit->toOne())); }: Code[0..1];
128+
attributeDeclare() { $this.attributeVar->map(v| $v->j_declare($this.attributeInit->toOne())); }: Code[0..1];
129+
textContentDeclare() { $this.textContentVar->map(v| $v->j_declare($this.textContentInit->toOne())); }: Code[0..1];
127130
}
128131

129132
function <<access.private>> meta::external::format::xml::executionPlan::platformBinding::legendJava::internalize::createClassElementNoSchemaMethods(jc:meta::external::language::java::metamodel::Class[1], ctxParam:Code[1], class:meta::pure::metamodel::type::Class<Any>[1], property:Property<Nil,Any|*>[0..1], path:String[1], context:GenerationContext[1]): meta::external::language::java::metamodel::Method[*]
@@ -176,21 +179,26 @@ function <<access.private>> meta::external::format::xml::executionPlan::platform
176179
);
177180
let withAttrsAdded = $propertyCodes.attributeVar->fold({v, c| $c->j_invoke('add', $v, $conventions->className(h_Element))}, $classElementVar);
178181

182+
let textContentVars = $propertyCodes.textContentVar;
183+
let hasTextContent = $textContentVars->isNotEmpty();
184+
let withTextContentAdded = $textContentVars->fold({v, c| $c->j_invoke('add', $v, $conventions->className(h_Element))}, $withAttrsAdded);
185+
179186
let elementVars = $propertyCodes.elementVar;
180187
let choiceVar = j_variable($conventions->className(h_Choice), '_choice');
181188
let choiceOf = $conventions->className(h_Choice)->j_invoke('of', [j_long(0), javaLongMax()]);
182189
let choiceWithElements = $elementVars->fold({v, c| $c->j_invoke('add', $v, $conventions->className(h_Choice))}, $choiceOf);
183-
let choiceDeclare = if($elementVars->isEmpty(),
190+
let choiceDeclare = if($elementVars->isEmpty() || $hasTextContent,
184191
| [],
185192
| $choiceVar->j_declare($choiceWithElements)
186193
);
187-
let withChoiceAdded = if($elementVars->isEmpty(),
188-
| $withAttrsAdded,
189-
| $withAttrsAdded->j_invoke('add', $choiceVar, $conventions->className(h_Element))
194+
let withChoiceAdded = if($elementVars->isEmpty() || $hasTextContent,
195+
| $withTextContentAdded,
196+
| $withTextContentAdded->j_invoke('add', $choiceVar, $conventions->className(h_Element))
190197
);
191198

192199
javaMethod('private', $conventions->className(h_Element), $conventions->elementMethodName($class), [$ctxParam, $minOccursParam, $maxOccursParam, $adderParam],
193200
$propertyCodes.attributeDeclare
201+
->concatenate($propertyCodes.textContentDeclare)
194202
->concatenate($propertyCodes.elementDeclare)
195203
->concatenate($choiceDeclare)
196204
->concatenate($classElementDeclare)
@@ -269,12 +277,16 @@ function <<access.private>> meta::external::format::xml::executionPlan::platform
269277
let textContentType = javaParameterizedType($conventions->className(h_TextContent), $dataClass);
270278
let textContent = j_new($textContentType, $addTo);
271279
let attributeAllowed = $prop.multiplicity == ZeroOne || $prop.multiplicity == PureOne;
280+
let isValueProperty = $prop.name->toOne() == 'value__';
281+
let textContentVar = j_variable($conventions->className(h_TextContent), $conventions->identifier($prop.name->toOne() + 'TextContent'));
272282

273283
^PropertyCodes(
274-
elementVar = $elementVar,
275-
elementInit = $conventions->className(h_Element)->j_invoke('ofLenient', [$pOccurs.first, $pOccurs.second, j_string($prop.name->toOne())])->j_invoke('add', $textContent, $conventions->className(h_Element)),
276-
attributeVar = if($attributeAllowed, |$attributeVar, |[]),
277-
attributeInit = if($attributeAllowed, |$conventions->className(h_Attribute)->j_invoke('ofLenient', [j_long(0), $pOccurs.second, j_string($prop.name->toOne()), $addTo]), |[])
284+
elementVar = if($isValueProperty, | [], | $elementVar),
285+
elementInit = if($isValueProperty, | [], | $conventions->className(h_Element)->j_invoke('ofLenient', [$pOccurs.first, $pOccurs.second, j_string($prop.name->toOne())])->j_invoke('add', $textContent, $conventions->className(h_Element))),
286+
attributeVar = if($attributeAllowed && !$isValueProperty, |$attributeVar, |[]),
287+
attributeInit = if($attributeAllowed && !$isValueProperty, |$conventions->className(h_Attribute)->j_invoke('ofLenient', [j_long(0), $pOccurs.second, j_string($prop.name->toOne()), $addTo]), |[]),
288+
textContentVar = if($isValueProperty, | $textContentVar, | []),
289+
textContentInit = if($isValueProperty, | $textContent, | [])
278290
);
279291
}
280292

legend-engine-xts-xml/legend-engine-xt-xml-runtime/src/test/java/org/finos/legend/engine/external/format/xml/test/TestXmlQueries.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,19 @@ public void testInternalizeWithAllDataType()
286286
MatcherAssert.assertThat(result, JsonMatchers.jsonEquals(resourceReader("queries/allDataTypeResult.json")));
287287
}
288288

289+
@Test
290+
public void testInternalizeWithTextContentAndAttribute()
291+
{
292+
String grammar = priceModel();
293+
PureModelContextData modelData = PureGrammarParser.newInstance().parseModel(grammar);
294+
295+
String result = runTest(modelData,
296+
"data:Byte[*]|test::model::Price->internalize(test::model::Binding, $data)->serialize(#{test::model::Price{_currency, value__}}#)",
297+
Maps.mutable.with("data", resource("queries/priceWithTextContentAndAttribute.xml")));
298+
299+
MatcherAssert.assertThat(result, JsonMatchers.jsonEquals(resourceReader("queries/priceWithTextContentAndAttributeResult.json")));
300+
}
301+
289302
private String schemalessBinding()
290303
{
291304
return "###ExternalFormat\n" +
@@ -325,4 +338,19 @@ private String allDataTypeModel()
325338
" modelIncludes: [ test::model::AllDataType ];\n" +
326339
"}\n";
327340
}
341+
342+
private String priceModel()
343+
{
344+
return "Class test::model::Price\n" +
345+
"{\n" +
346+
" _currency : String[1];\n" +
347+
" value__ : Decimal[1];\n" +
348+
"}\n\n" +
349+
"###ExternalFormat\n" +
350+
"Binding test::model::Binding\n" +
351+
"{\n" +
352+
" contentType: 'application/xml';\n" +
353+
" modelIncludes: [ test::model::Price ];\n" +
354+
"}\n";
355+
}
328356
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Price currency="USD">9999</Price>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"builder": {
3+
"_type": "json"
4+
},
5+
"values": {
6+
"_currency": "USD",
7+
"value__": 9999
8+
}
9+
}

0 commit comments

Comments
 (0)