Merge pull request #228 from ahdis/oliveregger_fml_xsitype

CDA xsi:type serialization when using fhir mapping language
This commit is contained in:
Grahame Grieve 2020-06-10 08:45:12 +10:00 committed by GitHub
commit 4d9ace1619
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 85 deletions

View File

@ -206,7 +206,7 @@ public class Property {
if (definition.getType().size() > 0) if (definition.getType().size() > 0)
return definition.getType().size() == 1 && ("Resource".equals(definition.getType().get(0).getCode()) || "DomainResource".equals(definition.getType().get(0).getCode())); return definition.getType().size() == 1 && ("Resource".equals(definition.getType().get(0).getCode()) || "DomainResource".equals(definition.getType().get(0).getCode()));
else else
return !definition.getPath().contains(".") && (structure.getKind() == StructureDefinitionKind.RESOURCE || structure.getKind() == StructureDefinitionKind.LOGICAL); return !definition.getPath().contains(".") && (structure.getKind() == StructureDefinitionKind.RESOURCE);
} }
public boolean isList() { public boolean isList() {

View File

@ -1,41 +1,28 @@
package org.hl7.fhir.r5.test; package org.hl7.fhir.r5.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.SimpleWorkerContext; import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.formats.IParser;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ResourceFactory;
import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.StructureMap; import org.hl7.fhir.r5.model.StructureMap;
import org.hl7.fhir.r5.terminologies.ConceptMapEngine;
import org.hl7.fhir.r5.test.utils.TestingUtilities; 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.TextFile; import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.cache.ToolsVersion;
import org.hl7.fhir.utilities.xml.XMLUtil; import org.hl7.fhir.utilities.xml.XMLUtil;
import org.hl7.fhir.validation.ValidationEngine;
import org.hl7.fhir.validation.instance.InstanceValidatorFactory; import org.hl7.fhir.validation.instance.InstanceValidatorFactory;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
@ -45,12 +32,13 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
public class FHIRMappingLanguageTests implements ITransformerServices { public class FHIRMappingLanguageTests {
private List<Resource> outputs = new ArrayList<Resource>(); private List<Resource> outputs = new ArrayList<Resource>();
static private ValidationEngine validationEngine;
static private SimpleWorkerContext context; static private SimpleWorkerContext context;
static private JsonParser jsonParser;
public static Stream<Arguments> data() public static Stream<Arguments> data()
throws FileNotFoundException, IOException, ParserConfigurationException, SAXException { throws FileNotFoundException, IOException, ParserConfigurationException, SAXException {
@ -67,91 +55,63 @@ public class FHIRMappingLanguageTests implements ITransformerServices {
@BeforeAll @BeforeAll
public static void setUp() throws Exception { public static void setUp() throws Exception {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION); validationEngine = new ValidationEngine("hl7.fhir.r4.core#4.0.1");
context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.r5.core", "current")); context = validationEngine.getContext();
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "any.xml"), "any.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ii.xml"), "ii.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cd.xml"), "cd.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ce.xml"), "ce.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ed.xml"), "ed.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "st.xml"), "st.xml", null);
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cda.xml"), "cda.xml", null);
for (StructureDefinition sd : context.getStructures()) {
if (!sd.hasSnapshot()) {
System.out.println("generate snapshot for " + sd.getUrl());
context.generateSnapshot(sd, true);
}
}
if (context.getValidatorFactory() == null) { if (context.getValidatorFactory() == null) {
context.setValidatorFactory(new InstanceValidatorFactory()); context.setValidatorFactory(new InstanceValidatorFactory());
} }
jsonParser = new JsonParser();
jsonParser.setOutputStyle(OutputStyle.PRETTY);
} }
@ParameterizedTest(name = "{index}: {0}") @ParameterizedTest(name = "{index}: {0}")
@MethodSource("data") @MethodSource("data")
public void test(String name, String source, String map, String output) throws Exception { public void test(String name, String source, String map, String output) throws Exception {
InputStream fileSource = TestingUtilities.loadTestResourceStream("r5", "fml", source); byte[] byteSource = TestingUtilities.loadTestResourceBytes("r5", "fml", source);
InputStream fileMap = TestingUtilities.loadTestResourceStream("r5", "fml", map); String stringMap = TestingUtilities.loadTestResource("r5", "fml", map);
String outputJson = TestingUtilities.loadTestResource("r5", "fml", output); String outputJson = TestingUtilities.loadTestResource("r5", "fml", output);
String fileOutputRes = TestingUtilities.tempFile("fml", output) + ".out"; String fileOutputRes = TestingUtilities.tempFile("fml", output) + ".out";
String fileOutputResOrig = TestingUtilities.tempFile("fml", output) + ".orig.out";
ByteArrayOutputStream s = null;
outputs.clear(); outputs.clear();
boolean ok = false;
String msg = null; String msg = null;
Resource resource = null;
try { try {
StructureMapUtilities scu = new StructureMapUtilities(context, this); StructureMap r = new org.hl7.fhir.r5.utils.StructureMapUtilities(context).parse(stringMap, map);
org.hl7.fhir.r5.elementmodel.Element src = Manager.parse(context, context.cacheResource(r);
new ByteArrayInputStream(TextFile.streamToBytes(fileSource)), FhirFormat.JSON); org.hl7.fhir.r5.elementmodel.Element element = validationEngine.transform(byteSource, FhirFormat.JSON, r.getUrl());
StructureMap structureMap = scu.parse(TextFile.streamToString(fileMap), name); s = new ByteArrayOutputStream();
String typeName = scu.getTargetType(structureMap).getType(); if (output.endsWith(".json"))
resource = ResourceFactory.createResource(typeName); new org.hl7.fhir.r5.elementmodel.JsonParser(context).compose(element, s, IParser.OutputStyle.PRETTY, null);
scu.transform(null, src, structureMap, resource); else
ok = true; new org.hl7.fhir.r5.elementmodel.XmlParser(context).compose(element, s, IParser.OutputStyle.PRETTY, null);
context.dropResource(r);
} catch (Exception e) { } catch (Exception e) {
ok = false; assertTrue(e.getMessage(), false);
msg = e.getMessage();
} }
if (ok) { if (output.endsWith("json")) {
ByteArrayOutputStream boas = new ByteArrayOutputStream(); msg = TestingUtilities.checkJsonSrcIsSame(s.toString(), outputJson);
jsonParser.compose(boas, resource);
String result = boas.toString();
log(result);
TextFile.bytesToFile(boas.toByteArray(), fileOutputRes);
msg = TestingUtilities.checkJsonSrcIsSame(result, outputJson);
assertTrue(msg, Utilities.noString(msg));
} else
assertEquals("Error, but proper output was expected (" + msg + ")", "$error", output);
}
@Override
public void log(String message) {
System.out.println(message);
}
@Override
public Base createType(Object appInfo, String name) throws FHIRException {
StructureDefinition sd = context.fetchResource(StructureDefinition.class, name);
if (sd != null && sd.getKind() == StructureDefinitionKind.LOGICAL) {
return Manager.build(context, sd);
} else { } else {
if (name.startsWith("http://hl7.org/fhir/StructureDefinition/")) TextFile.bytesToFile(s.toByteArray(), fileOutputRes);
name = name.substring("http://hl7.org/fhir/StructureDefinition/".length()); TextFile.bytesToFile(outputJson.getBytes(), fileOutputResOrig);
return ResourceFactory.createResourceOrType(name); msg = TestingUtilities.checkXMLIsSame(new FileInputStream(fileOutputRes), new FileInputStream(fileOutputResOrig));
} }
if (!Utilities.noString(msg)) {
System.out.print(s.toString());
}
assertTrue(msg, Utilities.noString(msg));
} }
@Override
public Base createResource(Object appInfo, Base res, boolean atRootofTransform) {
if (atRootofTransform)
outputs.add((Resource) res);
return res;
}
@Override
public Coding translate(Object appInfo, Coding source, String conceptMapUrl) throws FHIRException {
ConceptMapEngine cme = new ConceptMapEngine(context);
return cme.translate(source, conceptMapUrl);
}
@Override
public Base resolveReference(Object appContext, String url) throws FHIRException {
throw new FHIRException("resolveReference is not supported yet");
}
@Override
public List<Base> performSearch(Object appContext, String url) throws FHIRException {
throw new FHIRException("performSearch is not supported yet");
}
} }