Merge pull request #318 from ahdis/oe_structuremaps
structure maps: line comments and fhir path expression
This commit is contained in:
commit
f52297ae26
|
@ -284,7 +284,10 @@ public class StructureMapUtilities {
|
|||
b.append("\" = \"");
|
||||
b.append(Utilities.escapeJson(map.getName()));
|
||||
b.append("\"\r\n\r\n");
|
||||
|
||||
if (map.getDescription()!=null) {
|
||||
renderMultilineDoco(b, map.getDescription(), 0);
|
||||
b.append("\r\n");
|
||||
}
|
||||
renderConceptMaps(b, map);
|
||||
renderUses(b, map);
|
||||
renderImports(b, map);
|
||||
|
@ -392,8 +395,8 @@ public class StructureMapUtilities {
|
|||
}
|
||||
b.append("as ");
|
||||
b.append(s.getMode().toCode());
|
||||
b.append("\r\n");
|
||||
renderDoco(b, s.getDocumentation());
|
||||
b.append("\r\n");
|
||||
}
|
||||
if (map.hasStructure())
|
||||
b.append("\r\n");
|
||||
|
@ -416,6 +419,9 @@ public class StructureMapUtilities {
|
|||
}
|
||||
|
||||
private static void renderGroup(StringBuilder b, StructureMapGroupComponent g) {
|
||||
if (g.hasDocumentation()) {
|
||||
renderMultilineDoco(b, g.getDocumentation(), 0);
|
||||
}
|
||||
b.append("group ");
|
||||
b.append(g.getName());
|
||||
b.append("(");
|
||||
|
@ -464,6 +470,9 @@ public class StructureMapUtilities {
|
|||
}
|
||||
|
||||
private static void renderRule(StringBuilder b, StructureMapGroupRuleComponent r, int indent) {
|
||||
if (r.getDocumentation()!=null) {
|
||||
renderMultilineDoco(b, r.getDocumentation(),indent);
|
||||
}
|
||||
for (int i = 0; i < indent; i++)
|
||||
b.append(' ');
|
||||
boolean canBeAbbreviated = checkisSimple(r);
|
||||
|
@ -499,7 +508,6 @@ public class StructureMapUtilities {
|
|||
}
|
||||
if (r.hasRule()) {
|
||||
b.append(" then {\r\n");
|
||||
renderDoco(b, r.getDocumentation());
|
||||
for (StructureMapGroupRuleComponent ir : r.getRule()) {
|
||||
renderRule(b, ir, indent+2);
|
||||
}
|
||||
|
@ -539,8 +547,7 @@ public class StructureMapUtilities {
|
|||
}
|
||||
}
|
||||
b.append(";");
|
||||
renderDoco(b, r.getDocumentation());
|
||||
b.append("\r\n");
|
||||
b.append("\r\n");
|
||||
}
|
||||
|
||||
private static boolean matchesName(String n, List<StructureMapGroupRuleSourceComponent> source) {
|
||||
|
@ -653,13 +660,13 @@ public class StructureMapUtilities {
|
|||
renderTransformParam(b, rt.getParameter().get(0));
|
||||
} else if (rt.getTransform() == StructureMapTransform.EVALUATE && rt.getParameter().size() == 1) {
|
||||
b.append("(");
|
||||
b.append("\""+((StringType) rt.getParameter().get(0).getValue()).asStringValue()+"\"");
|
||||
b.append(((StringType) rt.getParameter().get(0).getValue()).asStringValue());
|
||||
b.append(")");
|
||||
} else if (rt.getTransform() == StructureMapTransform.EVALUATE && rt.getParameter().size() == 2) {
|
||||
b.append(rt.getTransform().toCode());
|
||||
b.append("(");
|
||||
b.append(((IdType) rt.getParameter().get(0).getValue()).asStringValue());
|
||||
b.append("\""+((StringType) rt.getParameter().get(1).getValue()).asStringValue()+"\"");
|
||||
b.append(((StringType) rt.getParameter().get(1).getValue()).asStringValue());
|
||||
b.append(")");
|
||||
} else {
|
||||
b.append(rt.getTransform().toCode());
|
||||
|
@ -718,9 +725,24 @@ public class StructureMapUtilities {
|
|||
private static void renderDoco(StringBuilder b, String doco) {
|
||||
if (Utilities.noString(doco))
|
||||
return;
|
||||
b.append(" // ");
|
||||
if (b!=null && b.length()>1 && b.charAt(b.length()-1)!='\n' && b.charAt(b.length()-1)!=' ') {
|
||||
b.append(" ");
|
||||
}
|
||||
b.append("// ");
|
||||
b.append(doco.replace("\r\n", " ").replace("\r", " ").replace("\n", " "));
|
||||
}
|
||||
|
||||
private static void renderMultilineDoco(StringBuilder b, String doco, int indent) {
|
||||
if (Utilities.noString(doco))
|
||||
return;
|
||||
String[] lines = doco.split("\\r?\\n");
|
||||
for(String line: lines) {
|
||||
for (int i = 0; i < indent; i++)
|
||||
b.append(' ');
|
||||
renderDoco(b, line);
|
||||
b.append("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
public StructureMap parse(String text, String srcName) throws FHIRException {
|
||||
FHIRLexer lexer = new FHIRLexer(text, srcName);
|
||||
|
@ -732,8 +754,9 @@ public class StructureMapUtilities {
|
|||
result.setUrl(lexer.readConstant("url"));
|
||||
lexer.token("=");
|
||||
result.setName(lexer.readConstant("name"));
|
||||
lexer.skipComments();
|
||||
|
||||
if (lexer.hasComment()) {
|
||||
result.setDescription(getMultiLineComments(lexer));
|
||||
}
|
||||
while (lexer.hasToken("conceptmap"))
|
||||
parseConceptMap(result, lexer);
|
||||
|
||||
|
@ -801,12 +824,24 @@ public class StructureMapUtilities {
|
|||
tgt.setCode(lexer.take());
|
||||
if (tgt.getCode().startsWith("\""))
|
||||
tgt.setCode(lexer.processConstant(tgt.getCode()));
|
||||
if (lexer.hasComment())
|
||||
tgt.setComment(lexer.take().substring(2).trim());
|
||||
if (lexer.hasComment())
|
||||
tgt.setComment(lexer.take().substring(2).trim());
|
||||
}
|
||||
lexer.token("}");
|
||||
}
|
||||
|
||||
|
||||
private String getMultiLineComments(FHIRLexer lexer) {
|
||||
String comment = null;
|
||||
while (lexer.hasComment()) {
|
||||
String newComment = lexer.take().substring(2).trim();
|
||||
if (comment == null) {
|
||||
comment = newComment;
|
||||
} else {
|
||||
comment += "\r\n"+newComment;
|
||||
}
|
||||
}
|
||||
return comment;
|
||||
}
|
||||
|
||||
private ConceptMapGroupComponent getGroup(ConceptMap map, String srcs, String tgts) {
|
||||
for (ConceptMapGroupComponent grp : map.getGroup()) {
|
||||
|
@ -850,6 +885,7 @@ public class StructureMapUtilities {
|
|||
|
||||
private void parseUses(StructureMap result, FHIRLexer lexer) throws FHIRException {
|
||||
lexer.token("uses");
|
||||
int currentLine = lexer.getCurrentLocation().getLine();
|
||||
StructureMapStructureComponent st = result.addStructure();
|
||||
st.setUrl(lexer.readConstant("url"));
|
||||
if (lexer.hasToken("alias")) {
|
||||
|
@ -859,25 +895,34 @@ public class StructureMapUtilities {
|
|||
lexer.token("as");
|
||||
st.setMode(StructureMapModelMode.fromCode(lexer.take()));
|
||||
lexer.skipToken(";");
|
||||
if (lexer.hasComment()) {
|
||||
if (lexer.hasComment() && currentLine == lexer.getCurrentLocation().getLine()) {
|
||||
st.setDocumentation(lexer.take().substring(2).trim());
|
||||
}
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private void parseImports(StructureMap result, FHIRLexer lexer) throws FHIRException {
|
||||
lexer.token("imports");
|
||||
int currentLine = lexer.getCurrentLocation().getLine();
|
||||
result.addImport(lexer.readConstant("url"));
|
||||
lexer.skipToken(";");
|
||||
if (lexer.hasComment()) {
|
||||
if (lexer.hasComment() && currentLine == lexer.getCurrentLocation().getLine()) {
|
||||
lexer.next();
|
||||
}
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private void parseGroup(StructureMap result, FHIRLexer lexer) throws FHIRException {
|
||||
String comment = null;
|
||||
if (lexer.hasComment()) {
|
||||
comment = getMultiLineComments(lexer);
|
||||
if (lexer.done()) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
lexer.token("group");
|
||||
StructureMapGroupComponent group = result.addGroup();
|
||||
if (comment != null) {
|
||||
group.setDocumentation(comment);
|
||||
}
|
||||
boolean newFmt = false;
|
||||
if (lexer.hasToken("for")) {
|
||||
lexer.token("for");
|
||||
|
@ -923,7 +968,6 @@ public class StructureMapUtilities {
|
|||
}
|
||||
lexer.token("{");
|
||||
}
|
||||
lexer.skipComments();
|
||||
if (newFmt) {
|
||||
while (!lexer.hasToken("}")) {
|
||||
if (lexer.done())
|
||||
|
@ -931,6 +975,7 @@ public class StructureMapUtilities {
|
|||
parseRule(result, group.getRule(), lexer, true);
|
||||
}
|
||||
} else {
|
||||
lexer.skipComments();
|
||||
while (lexer.hasToken("input"))
|
||||
parseInput(group, lexer, false);
|
||||
while (!lexer.hasToken("endgroup")) {
|
||||
|
@ -942,7 +987,6 @@ public class StructureMapUtilities {
|
|||
lexer.next();
|
||||
if (newFmt && lexer.hasToken(";"))
|
||||
lexer.next();
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private void parseInput(StructureMapGroupComponent group, FHIRLexer lexer, boolean newFmt) throws FHIRException {
|
||||
|
@ -969,12 +1013,19 @@ public class StructureMapUtilities {
|
|||
|
||||
private void parseRule(StructureMap map, List<StructureMapGroupRuleComponent> list, FHIRLexer lexer, boolean newFmt) throws FHIRException {
|
||||
StructureMapGroupRuleComponent rule = new StructureMapGroupRuleComponent();
|
||||
list.add(rule);
|
||||
if (!newFmt) {
|
||||
rule.setName(lexer.takeDottedToken());
|
||||
lexer.token(":");
|
||||
lexer.token("for");
|
||||
} else {
|
||||
if (lexer.hasComment()) {
|
||||
rule.setDocumentation(this.getMultiLineComments(lexer));
|
||||
if (lexer.hasToken("}")) {
|
||||
return ; // catched a comment at the end
|
||||
}
|
||||
}
|
||||
}
|
||||
list.add(rule);
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
parseSource(rule, lexer);
|
||||
|
@ -996,10 +1047,6 @@ public class StructureMapUtilities {
|
|||
lexer.token("then");
|
||||
if (lexer.hasToken("{")) {
|
||||
lexer.token("{");
|
||||
if (lexer.hasComment()) {
|
||||
rule.setDocumentation(lexer.take().substring(2).trim());
|
||||
}
|
||||
lexer.skipComments();
|
||||
while (!lexer.hasToken("}")) {
|
||||
if (lexer.done())
|
||||
throw lexer.error("premature termination expecting '}' in nested group");
|
||||
|
@ -1016,7 +1063,7 @@ public class StructureMapUtilities {
|
|||
}
|
||||
}
|
||||
} else if (lexer.hasComment()) {
|
||||
rule.setDocumentation(lexer.take().substring(2).trim());
|
||||
rule.setDocumentation(getMultiLineComments(lexer));
|
||||
}
|
||||
if (isSimpleSyntax(rule)) {
|
||||
rule.getSourceFirstRep().setVariable(AUTO_VAR_NAME);
|
||||
|
@ -1041,7 +1088,6 @@ public class StructureMapUtilities {
|
|||
}
|
||||
lexer.token(";");
|
||||
}
|
||||
lexer.skipComments();
|
||||
}
|
||||
|
||||
private boolean isSimpleSyntax(StructureMapGroupRuleComponent rule) {
|
||||
|
|
|
@ -10,23 +10,23 @@ import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
|||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.StructureMap;
|
||||
import org.hl7.fhir.r5.model.StructureMap.StructureMapGroupRuleTargetComponent;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.r5.utils.StructureMapUtilities;
|
||||
import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled // org.hl7.fhir.exceptions.FHIRException: Unable to resolve package id hl7.fhir.core#4.0.0
|
||||
public class StructureMapUtilitiesTest implements ITransformerServices {
|
||||
|
||||
static private SimpleWorkerContext context;
|
||||
|
||||
// @BeforeAll
|
||||
|
||||
@BeforeAll
|
||||
static public void setUp() throws Exception {
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.core", "4.0.0"));
|
||||
context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.r4.core", "4.0.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -38,7 +38,43 @@ public class StructureMapUtilitiesTest implements ITransformerServices {
|
|||
// StructureMap/ActivityDefinition3to4: StructureMap.group[3].rule[2].name error id value '"expression"' is not valid
|
||||
assertEquals("expression", structureMap.getGroup().get(2).getRule().get(1).getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void assertSerializeDeserialize(StructureMap structureMap) {
|
||||
assertEquals("syntax", structureMap.getName());
|
||||
assertEquals("Title of this map\r\nAuthor", structureMap.getDescription());
|
||||
assertEquals("http://github.com/FHIR/fhir-test-cases/r5/fml/syntax", structureMap.getUrl());
|
||||
assertEquals("Patient", structureMap.getStructure().get(0).getAlias());
|
||||
assertEquals("http://hl7.org/fhir/StructureDefinition/Patient", structureMap.getStructure().get(0).getUrl());
|
||||
assertEquals("Source Documentation", structureMap.getStructure().get(0).getDocumentation());
|
||||
assertEquals("http://hl7.org/fhir/StructureDefinition/Patient", structureMap.getStructure().get(0).getUrl());
|
||||
assertEquals("http://hl7.org/fhir/StructureDefinition/Basic", structureMap.getStructure().get(1).getUrl());
|
||||
assertEquals("Target Documentation", structureMap.getStructure().get(1).getDocumentation());
|
||||
assertEquals("Groups\r\nrule for patient group", structureMap.getGroup().get(0).getDocumentation());
|
||||
assertEquals("Comment to rule", structureMap.getGroup().get(0).getRule().get(0).getDocumentation());
|
||||
assertEquals("Copy identifier short syntax", structureMap.getGroup().get(0).getRule().get(1).getDocumentation());
|
||||
|
||||
StructureMapGroupRuleTargetComponent target = structureMap.getGroup().get(0).getRule().get(2).getTarget().get(1);
|
||||
assertEquals("'urn:uuid:' + r.lower()", target.getParameter().get(0).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyntax() throws IOException, FHIRException {
|
||||
StructureMapUtilities scu = new StructureMapUtilities(context, this);
|
||||
String fileMap = TestingUtilities.loadTestResource("r5", "fml", "syntax.map");
|
||||
System.out.println(fileMap);
|
||||
|
||||
StructureMap structureMap = scu.parse(fileMap, "Syntax");
|
||||
assertSerializeDeserialize(structureMap);
|
||||
|
||||
String renderedMap = StructureMapUtilities.render(structureMap);
|
||||
StructureMap map = scu.parse(renderedMap, "Syntax");
|
||||
System.out.println(map);
|
||||
assertSerializeDeserialize(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
}
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -17,7 +17,7 @@
|
|||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.1.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.33</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.34-SNAPSHOT</validator_test_case_version>
|
||||
<junit_jupiter_version>5.6.2</junit_jupiter_version>
|
||||
<maven_surefire_version>3.0.0-M4</maven_surefire_version>
|
||||
<jacoco_version>0.8.5</jacoco_version>
|
||||
|
|
Loading…
Reference in New Issue