Test Classes

This commit is contained in:
admin 2019-06-14 05:24:11 -05:00
parent e58224e63b
commit 3b35e6add4
11 changed files with 694 additions and 75 deletions

View File

@ -72,8 +72,7 @@
<dependency> <dependency>
<groupId>org.apache.jena</groupId> <groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId> <artifactId>apache-jena-libs</artifactId>
<type>pom</type> <optional>true</optional>
<version>3.11.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>

View File

@ -20,6 +20,7 @@ import ca.uhn.fhir.util.ReflectionUtil;
import ca.uhn.fhir.util.VersionUtil; import ca.uhn.fhir.util.VersionUtil;
import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.FhirValidator;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.jena.riot.Lang;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
@ -640,7 +641,7 @@ public class FhirContext {
* </p> * </p>
*/ */
public IParser newRDFParser() { public IParser newRDFParser() {
return new RDFParser(this, myParserErrorHandler); return new RDFParser(this, myParserErrorHandler, Lang.TURTLE);
} }

View File

@ -26,18 +26,13 @@ import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.util.ElementUtil; import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.RDFUtil; import ca.uhn.fhir.util.rdf.RDFUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.riot.Lang; import org.apache.jena.riot.Lang;
import org.apache.jena.riot.system.StreamRDF; import org.apache.jena.riot.system.StreamRDF;
import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.instance.model.api.*;
import java.io.Reader; import java.io.*;
import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -71,8 +66,8 @@ public class RDFParser extends BaseParser {
protected void doEncodeResourceToWriter(final IBaseResource resource, protected void doEncodeResourceToWriter(final IBaseResource resource,
final Writer writer, final Writer writer,
final EncodeContext encodeContext) { final EncodeContext encodeContext) {
StreamRDF eventWriter = RDFUtil.createRDFWriter(writer, this.lang); StreamRDF eventWriter = RDFUtil.createRDFWriter(writer, this.lang);
eventWriter.base(FHIR_NS);
encodeResourceToRDFStreamWriter(resource, eventWriter, encodeContext); encodeResourceToRDFStreamWriter(resource, eventWriter, encodeContext);
} }
@ -80,7 +75,8 @@ public class RDFParser extends BaseParser {
protected <T extends IBaseResource> T doParseResource(final Class<T> resourceType, protected <T extends IBaseResource> T doParseResource(final Class<T> resourceType,
final Reader reader) throws DataFormatException { final Reader reader) throws DataFormatException {
StreamRDF streamReader = createStreamReader(reader); StreamRDF streamReader = RDFUtil.createRDFReader(reader, this.lang);
streamReader.base(FHIR_NS);
return parseResource(resourceType, streamReader); return parseResource(resourceType, streamReader);
} }
@ -94,11 +90,6 @@ public class RDFParser extends BaseParser {
return this; return this;
} }
private StreamRDF createStreamReader(Reader reader) {
return RDFUtil.createRDFReader(reader, this.lang);
}
private void encodeResourceToRDFStreamWriter(final IBaseResource resource, private void encodeResourceToRDFStreamWriter(final IBaseResource resource,
final StreamRDF streamWriter, final StreamRDF streamWriter,
final boolean containedResource, final boolean containedResource,
@ -113,22 +104,12 @@ public class RDFParser extends BaseParser {
super.containResourcesForEncoding(resource); super.containResourcesForEncoding(resource);
} }
streamWriter.start();
streamWriter.base(FHIR_NS);
Model model = ModelFactory.createDefaultModel();
if (resource instanceof IAnyResource) { if (resource instanceof IAnyResource) {
// HL7.org Structures // HL7.org Structures
if (resourceId != null) { if (resourceId != null) {
writeCommentsPre(streamWriter, resourceId); writeCommentsPre(streamWriter, resourceId);
Resource element = model.createResource(resourceId.getBaseUrl());
Property property = model.createProperty("value", resourceId.getIdPart());
element.addProperty(property, resourceId.getIdPart());
streamWriter.start(); streamWriter.start();
streamWriter.prefix("value", resourceId.getIdPart()); streamWriter.triple(RDFUtil.triple("<value> " + resourceId.getIdPart() + " </value>"));
streamWriter.finish(); streamWriter.finish();
writeCommentsPost(streamWriter, resourceId); writeCommentsPost(streamWriter, resourceId);
} }
@ -140,7 +121,7 @@ public class RDFParser extends BaseParser {
// DSTU2+ // DSTU2+
if (resourceId != null) { if (resourceId != null) {
streamWriter.start(); streamWriter.start();
streamWriter.prefix("value", resourceId.getIdPart()); streamWriter.triple(RDFUtil.triple("<value> " + resourceId.getIdPart() + " </value>"));
encodeExtensionsIfPresent(resource, streamWriter, resourceId, false, encodeContext); encodeExtensionsIfPresent(resource, streamWriter, resourceId, false, encodeContext);
streamWriter.finish(); streamWriter.finish();
writeCommentsPost(streamWriter, resourceId); writeCommentsPost(streamWriter, resourceId);
@ -163,7 +144,7 @@ public class RDFParser extends BaseParser {
for (IIdType profile : profiles) { for (IIdType profile : profiles) {
streamWriter.start(); streamWriter.start();
streamWriter.prefix("value", profile.getValue()); streamWriter.triple(RDFUtil.triple("<value> " + profile.getValue() + " </value>"));
streamWriter.finish(); streamWriter.finish();
} }
for (BaseCodingDt securityLabel : securityLabels) { for (BaseCodingDt securityLabel : securityLabels) {
@ -177,9 +158,9 @@ public class RDFParser extends BaseParser {
continue; continue;
} }
streamWriter.start(); streamWriter.start();
streamWriter.prefix("system", tag.getScheme()); streamWriter.triple(RDFUtil.triple("<system> " + tag.getScheme() + " </system>"));
streamWriter.prefix("code", tag.getTerm()); streamWriter.triple(RDFUtil.triple("<code> " + tag.getTerm() + " </code>"));
streamWriter.prefix("display", tag.getLabel()); streamWriter.triple(RDFUtil.triple("<display> " + tag.getLabel() + " </display>"));
streamWriter.finish(); streamWriter.finish();
} }
} }
@ -188,8 +169,8 @@ public class RDFParser extends BaseParser {
*/ */
if (resource instanceof IBaseBinary) { if (resource instanceof IBaseBinary) {
IBaseBinary bin = (IBaseBinary) resource; IBaseBinary bin = (IBaseBinary) resource;
streamWriter.prefix("contentType", bin.getContentType()); streamWriter.triple(RDFUtil.triple("<contentType> " + bin.getContentType() + " </contentType>"));
streamWriter.prefix("content", bin.getContentAsBase64()); streamWriter.triple(RDFUtil.triple("<content> " + bin.getContentAsBase64() + " </content>"));
} else { } else {
encodeCompositeElementToStreamWriter(resource, resource, streamWriter, containedResource, new CompositeChildElement(resDef, encodeContext), encodeContext); encodeCompositeElementToStreamWriter(resource, resource, streamWriter, containedResource, new CompositeChildElement(resDef, encodeContext), encodeContext);
} }
@ -251,7 +232,7 @@ public class RDFParser extends BaseParser {
if (StringUtils.isNotBlank(encodedValue) || !hasNoExtensions(value)) { if (StringUtils.isNotBlank(encodedValue) || !hasNoExtensions(value)) {
eventWriter.start(); eventWriter.start();
if (StringUtils.isNotBlank(encodedValue)) { if (StringUtils.isNotBlank(encodedValue)) {
eventWriter.prefix("value", encodedValue); eventWriter.triple(RDFUtil.triple("<value> " + encodedValue + " </value>"));
} }
encodeExtensionsIfPresent(resource, eventWriter, element, includedResource, encodeContext); encodeExtensionsIfPresent(resource, eventWriter, element, includedResource, encodeContext);
eventWriter.finish(); eventWriter.finish();
@ -266,10 +247,10 @@ public class RDFParser extends BaseParser {
eventWriter.start(); eventWriter.start();
String elementId = getCompositeElementId(element); String elementId = getCompositeElementId(element);
if (isNotBlank(elementId)) { if (isNotBlank(elementId)) {
eventWriter.prefix("id", elementId); eventWriter.triple(RDFUtil.triple("<id> " + elementId + " </id>"));
} }
if (value != null) { if (value != null) {
eventWriter.prefix("value", value); eventWriter.triple(RDFUtil.triple("<value> " + value + " </value>"));
} }
encodeExtensionsIfPresent(resource, eventWriter, element, includedResource, encodeContext); encodeExtensionsIfPresent(resource, eventWriter, element, includedResource, encodeContext);
eventWriter.finish(); eventWriter.finish();
@ -281,10 +262,10 @@ public class RDFParser extends BaseParser {
eventWriter.start(); eventWriter.start();
String elementId = getCompositeElementId(element); String elementId = getCompositeElementId(element);
if (isNotBlank(elementId)) { if (isNotBlank(elementId)) {
eventWriter.prefix("id", elementId); eventWriter.triple(RDFUtil.triple("<id> " + elementId + " </id>"));
} }
if (isNotBlank(extensionUrl)) { if (isNotBlank(extensionUrl)) {
eventWriter.prefix("url", extensionUrl); eventWriter.triple(RDFUtil.triple("<url> " + extensionUrl + " </url>"));
} }
encodeCompositeElementToStreamWriter(resource, element, eventWriter, includedResource, parent, encodeContext); encodeCompositeElementToStreamWriter(resource, element, eventWriter, includedResource, parent, encodeContext);
eventWriter.finish(); eventWriter.finish();
@ -369,11 +350,11 @@ public class RDFParser extends BaseParser {
String elementId = getCompositeElementId(next); String elementId = getCompositeElementId(next);
if (isNotBlank(elementId)) { if (isNotBlank(elementId)) {
eventWriter.prefix("id", elementId); eventWriter.triple(RDFUtil.triple("<id> " + elementId + " </id>"));
} }
String url = getExtensionUrl(next.getUrl()); String url = getExtensionUrl(next.getUrl());
eventWriter.prefix("url", url); eventWriter.triple(RDFUtil.triple("<url> " + url + " </url>"));
if (next.getValue() != null) { if (next.getValue() != null) {
IBaseDatatype value = next.getValue(); IBaseDatatype value = next.getValue();
@ -426,32 +407,27 @@ public class RDFParser extends BaseParser {
} }
} }
private void encodeExtension(final IBaseResource theResource, private void encodeExtension(final IBaseResource resource,
final StreamRDF theEventWriter, final StreamRDF eventWriter,
final boolean theContainedResource, final boolean containedResource,
final CompositeChildElement nextChildElem, final CompositeChildElement nextChildElem,
final BaseRuntimeChildDefinition nextChild, final BaseRuntimeChildDefinition nextChild,
final IBase nextValue, final IBase nextValue,
final String childName, final String childName,
final String extensionUrl, final String extensionUrl,
final BaseRuntimeElementDefinition<?> childDef, final BaseRuntimeElementDefinition<?> childDef,
final EncodeContext theEncodeContext) { final EncodeContext encodeContext) {
BaseRuntimeDeclaredChildDefinition extDef = (BaseRuntimeDeclaredChildDefinition) nextChild; BaseRuntimeDeclaredChildDefinition extDef = (BaseRuntimeDeclaredChildDefinition) nextChild;
if (extDef.isModifier()) { eventWriter.start();
theEventWriter.start();
} else {
theEventWriter.start();
}
String elementId = getCompositeElementId(nextValue); String elementId = getCompositeElementId(nextValue);
if (isNotBlank(elementId)) { if (isNotBlank(elementId)) {
theEventWriter.prefix("id", elementId); eventWriter.triple(RDFUtil.triple("<id> " + elementId + " </id>"));
} }
eventWriter.triple(RDFUtil.triple("<url> " + extensionUrl + " </url>"));
theEventWriter.prefix("url", extensionUrl); encodeChildElementToStreamWriter(resource, eventWriter, nextChild, nextValue, childName,
encodeChildElementToStreamWriter(theResource, theEventWriter, nextChild, nextValue, childName, childDef, null, containedResource, nextChildElem, encodeContext);
childDef, null, theContainedResource, nextChildElem, theEncodeContext); eventWriter.finish();
theEventWriter.finish();
} }
private void encodeCompositeElementToStreamWriter(final IBaseResource resource, private void encodeCompositeElementToStreamWriter(final IBaseResource resource,

View File

@ -42,7 +42,7 @@ public class Constants {
*/ */
public static final Set<String> CORS_ALLWED_METHODS; public static final Set<String> CORS_ALLWED_METHODS;
public static final String CT_FHIR_JSON = "application/json+fhir"; public static final String CT_FHIR_JSON = "application/json+fhir";
public static final String CT_FHIR_RDF = "application/x-turtle"; public static final String CT_RDF_TURTLE = "application/x-turtle";
/** /**
* The FHIR MimeType for JSON encoding in FHIR DSTU3+ * The FHIR MimeType for JSON encoding in FHIR DSTU3+
*/ */
@ -71,7 +71,7 @@ public class Constants {
public static final String FORMAT_HTML = "html"; public static final String FORMAT_HTML = "html";
public static final String FORMAT_JSON = "json"; public static final String FORMAT_JSON = "json";
public static final String FORMAT_XML = "xml"; public static final String FORMAT_XML = "xml";
public static final String FORMAT_RDF = "text/turtle"; public static final String FORMAT_TURTLE = "text/turtle";
/** /**

View File

@ -44,7 +44,7 @@ public enum EncodingEnum {
} }
}, },
RDF(Constants.CT_FHIR_RDF, Constants.CT_FHIR_RDF, Constants.FORMAT_RDF) { RDF(Constants.CT_RDF_TURTLE, Constants.CT_RDF_TURTLE, Constants.FORMAT_TURTLE) {
@Override @Override
public IParser newParser(FhirContext theContext) { public IParser newParser(FhirContext theContext) {
return theContext.newRDFParser(); return theContext.newRDFParser();
@ -61,12 +61,6 @@ public enum EncodingEnum {
*/ */
public static final String XML_PLAIN_STRING = "xml"; public static final String XML_PLAIN_STRING = "xml";
/**
* "ttl"
*/
public static final String TTL_PLAIN_STRING = "ttl";
private static Map<String, EncodingEnum> ourContentTypeToEncoding; private static Map<String, EncodingEnum> ourContentTypeToEncoding;
private static Map<String, EncodingEnum> ourContentTypeToEncodingLegacy; private static Map<String, EncodingEnum> ourContentTypeToEncodingLegacy;
private static Map<String, EncodingEnum> ourContentTypeToEncodingStrict; private static Map<String, EncodingEnum> ourContentTypeToEncodingStrict;

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.util; package ca.uhn.fhir.util.rdf;
/* /*
* #%L * #%L
@ -22,15 +22,16 @@ package ca.uhn.fhir.util;
import org.apache.commons.io.input.ReaderInputStream; import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.io.output.WriterOutputStream; import org.apache.commons.io.output.WriterOutputStream;
import org.apache.jena.graph.Triple;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.riot.Lang; import org.apache.jena.riot.Lang;
import org.apache.jena.riot.system.StreamRDF; import org.apache.jena.riot.system.StreamRDF;
import org.apache.jena.riot.system.StreamRDFWriter; import org.apache.jena.riot.system.StreamRDFWriter;
import java.io.Reader; import java.io.*;
import java.io.Writer; import java.nio.charset.Charset;
import java.util.Collections; import java.util.*;
import java.util.HashMap;
import java.util.Map;
public class RDFUtil { public class RDFUtil {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RDFUtil.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RDFUtil.class);
@ -42,13 +43,19 @@ public class RDFUtil {
} }
public static StreamRDF createRDFWriter(final Writer writer, final Lang lang) { public static StreamRDF createRDFWriter(final Writer writer, final Lang lang) {
WriterOutputStream stream = new WriterOutputStream(writer); WriterOutputStream wos = new WriterOutputStream(writer, Charset.defaultCharset());
return StreamRDFWriter.getWriterStream(stream, lang); return StreamRDFWriter.getWriterStream(wos, lang);
} }
public static StreamRDF createRDFReader(final Reader reader, final Lang lang) { public static StreamRDF createRDFReader(final Reader reader, final Lang lang) {
ReaderInputStream stream = new ReaderInputStream(reader); ReaderInputStream ris = new ReaderInputStream(reader, Charset.defaultCharset());
return StreamRDFWriter.getWriterStream(null, lang); return StreamRDFWriter.getWriterStream(null, lang);
} }
public static Triple triple(String tripleAsTurtle) {
Model m = ModelFactory.createDefaultModel();
m.read(new StringReader(tripleAsTurtle), "urn:x-base:", "TURTLE");
return m.listStatements().next().asTriple();
}
} }

View File

@ -0,0 +1,82 @@
package ca.uhn.fhir.util.rdf;
import java.util.HashSet;
import java.util.LinkedList;
import org.apache.jena.graph.Triple;
import org.apache.jena.riot.system.StreamRDF;
import org.apache.jena.sparql.core.Quad;
/**
* Wraps another {@link StreamRDF} and attempts to remove duplicate
* triples and quads. To maintain streaming, duplicates are only
* removed within a sliding window of configurable size. Default
* size is 10000 triples and quads.
*/
public class StreamRDFDedup implements StreamRDF {
private final StreamRDF wrapped;
private final int windowSize;
private final HashSet<Object> tripleAndQuadCache;
private final LinkedList<Object> tripleAndQuadList = new LinkedList<Object>();
public StreamRDFDedup(StreamRDF wrapped) {
this(wrapped, 10000);
}
public StreamRDFDedup(StreamRDF wrapped, int windowSize) {
this.wrapped = wrapped;
this.windowSize = windowSize;
// Initial capacity big enough to avoid rehashing
this.tripleAndQuadCache = new HashSet<Object>(windowSize * 3 / 2);
}
@Override
public void start() {
wrapped.start();
}
@Override
public void triple(Triple triple) {
if (!seen(triple)) {
wrapped.triple(triple);
}
}
@Override
public void quad(Quad quad) {
if (!seen(quad)) {
wrapped.quad(quad);
}
}
@Override
public void base(String base) {
wrapped.base(base);
}
@Override
public void prefix(String prefix, String iri) {
wrapped.prefix(prefix, iri);
}
@Override
public void finish() {
wrapped.finish();
}
private boolean seen(Object tuple) {
if (tripleAndQuadCache.contains(tuple)) {
return true;
}
tripleAndQuadCache.add(tuple);
tripleAndQuadList.add(tuple);
if (tripleAndQuadList.size() > windowSize) {
forgetOldest();
}
return false;
}
private void forgetOldest() {
tripleAndQuadCache.remove(tripleAndQuadList.removeFirst());
}
}

View File

@ -0,0 +1,90 @@
package ca.uhn.fhir.util.rdf;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Map.Entry;
import org.apache.jena.atlas.io.IndentedWriter;
import org.apache.jena.graph.Triple;
import org.apache.jena.riot.system.RiotLib;
import org.apache.jena.riot.system.StreamOps;
import org.apache.jena.riot.system.StreamRDF;
import org.apache.jena.riot.writer.WriterStreamRDFBlocks;
import org.apache.jena.riot.writer.WriterStreamRDFPlain;
import org.apache.jena.shared.PrefixMapping;
import org.apache.jena.shared.impl.PrefixMappingImpl;
import org.apache.jena.vocabulary.RDF;
/**
* Writes an iterator over triples to N-Triples or Turtle
* in a streaming fashion, that is, without needing to hold
* the entire thing in memory.
* <p>
* Instances are single-use.
* <p>
* There doesn't seem to be a pre-packaged version of this
* functionality in Jena/ARQ that doesn't require a Graph or Model.
*/
public class StreamingRDFWriter {
private final OutputStream out;
private final Iterator<Triple> triples;
private int dedupWindowSize = 10000;
public StreamingRDFWriter(OutputStream out, Iterator<Triple> triples) {
this.out = out;
this.triples = triples;
}
public void setDedupWindowSize(int newSize) {
this.dedupWindowSize = newSize;
}
public void writeNTriples() {
StreamRDF writer = new WriterStreamRDFPlain(new IndentedWriter(out));
if (dedupWindowSize > 0) {
writer = new StreamRDFDedup(writer, dedupWindowSize);
}
writer.start();
StreamOps.sendTriplesToStream(triples, writer);
writer.finish();
}
public void writeTurtle(String baseIRI, PrefixMapping prefixes, boolean writeBase) {
// Auto-register RDF prefix so that rdf:type is displayed well
// All other prefixes come from the query and should be as author intended
prefixes = ensureRDFPrefix(prefixes);
if (writeBase) {
// Jena's streaming Turtle writers don't output base even if it is provided,
// so we write it directly.
IndentedWriter w = new IndentedWriter(out);
RiotLib.writeBase(w, baseIRI);
w.flush();
}
StreamRDF writer = new WriterStreamRDFBlocks(out);
if (dedupWindowSize > 0) {
writer = new StreamRDFDedup(writer, dedupWindowSize);
}
writer.start();
writer.base(baseIRI);
for (Entry<String, String> e : prefixes.getNsPrefixMap().entrySet()) {
writer.prefix(e.getKey(), e.getValue());
}
StreamOps.sendTriplesToStream(triples, writer);
writer.finish();
}
private PrefixMapping ensureRDFPrefix(PrefixMapping prefixes) {
// Some prefix already registered for the RDF namespace -- good enough
if (prefixes.getNsURIPrefix(RDF.getURI()) != null) return prefixes;
// rdf: is registered to something else -- give up
if (prefixes.getNsPrefixURI("rdf") != null) return prefixes;
// Register rdf:
PrefixMapping newPrefixes = new PrefixMappingImpl();
newPrefixes.setNsPrefixes(prefixes);
newPrefixes.setNsPrefix("rdf", RDF.getURI());
return newPrefixes;
}
}

View File

@ -0,0 +1,406 @@
package ca.uhn.fhir.parser;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.util.TestUtil;
import com.google.common.collect.Sets;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.r4.model.*;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.*;
public class RDFParserR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(RDFParserR4Test.class);
private static FhirContext ourCtx = FhirContext.forR4();
/*
private Bundle createBundleWithPatient() {
Bundle b = new Bundle();
b.setId("BUNDLEID");
b.getMeta().addProfile("http://FOO");
Patient p = new Patient();
p.setId("PATIENTID");
p.getMeta().addProfile("http://BAR");
p.addName().addGiven("GIVEN");
b.addEntry().setResource(p);
return b;
}
*/
@Test
public void testDontStripVersions() {
/*
FhirContext ctx = FhirContext.forR4();
ctx.getParserOptions().setDontStripVersionsFromReferencesAtPaths("QuestionnaireResponse.questionnaire");
QuestionnaireResponse qr = new QuestionnaireResponse();
qr.getQuestionnaireElement().setValueAsString("Questionnaire/123/_history/456");
String output = ctx.newRDFParser().setPrettyPrint(true).encodeResourceToString(qr);
ourLog.info(output);
assertThat(output, containsString("\"Questionnaire/123/_history/456\""));
*/
}
@Test
public void testDuplicateContainedResourcesNotOutputtedTwice() {
/*MedicationDispense md = new MedicationDispense();
MedicationRequest mr = new MedicationRequest();
md.addAuthorizingPrescription().setResource(mr);
Medication med = new Medication();
md.setMedication(new Reference(med));
mr.setMedication(new Reference(med));
String encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(md);
ourLog.info(encoded);
int idx = encoded.indexOf("\"Medication\"");
assertNotEquals(-1, idx);
idx = encoded.indexOf("\"Medication\"", idx + 1);
assertEquals(-1, idx);
*/
}
/**
* See #814
*/
@Test
public void testDuplicateContainedResourcesNotOutputtedTwiceWithManualIds() {
/*
MedicationDispense md = new MedicationDispense();
MedicationRequest mr = new MedicationRequest();
mr.setId("#MR");
md.addAuthorizingPrescription().setResource(mr);
Medication med = new Medication();
med.setId("#MED");
md.setMedication(new Reference(med));
mr.setMedication(new Reference(med));
String encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(md);
ourLog.info(encoded);
int idx = encoded.indexOf("\"Medication\"");
assertNotEquals(-1, idx);
idx = encoded.indexOf("\"Medication\"", idx + 1);
assertEquals(-1, idx);
*/
}
/*
* See #814
*/
@Test
public void testDuplicateContainedResourcesNotOutputtedTwiceWithManualIdsAndManualAddition() {
/*
MedicationDispense md = new MedicationDispense();
MedicationRequest mr = new MedicationRequest();
mr.setId("#MR");
md.addAuthorizingPrescription().setResource(mr);
Medication med = new Medication();
med.setId("#MED");
Reference medRef = new Reference();
medRef.setReference("#MED");
md.setMedication(medRef);
mr.setMedication(medRef);
md.getContained().add(mr);
md.getContained().add(med);
String encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(md);
ourLog.info(encoded);
int idx = encoded.indexOf("\"Medication\"");
assertNotEquals(-1, idx);
idx = encoded.indexOf("\"Medication\"", idx + 1);
assertEquals(-1, idx);
*/
}
@Test
public void testEncodeAndParseUnicodeCharacterInNarrative() {
/*
Patient p = new Patient();
p.getText().getDiv().setValueAsString("<div>Copy © 1999</div>");
String encoded = ourCtx.newRDFParser().encodeResourceToString(p);
ourLog.info(encoded);
p = (Patient) ourCtx.newRDFParser().parseResource(encoded);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">Copy &copy; 1999</div>", p.getText().getDivAsString());
*/
}
@Test
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalFirst() {
/*
Observation obs = new Observation();
Patient pt = new Patient();
pt.setId("#1");
pt.addName().setFamily("FAM");
obs.getSubject().setReference("#1");
obs.getContained().add(pt);
Encounter enc = new Encounter();
enc.setStatus(Encounter.EncounterStatus.ARRIVED);
obs.getEncounter().setResource(enc);
String encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(obs);
ourLog.info(encoded);
obs = ourCtx.newRDFParser().parseResource(Observation.class, encoded);
assertEquals("#1", obs.getContained().get(0).getId());
assertEquals("#2", obs.getContained().get(1).getId());
pt = (Patient) obs.getSubject().getResource();
assertEquals("FAM", pt.getNameFirstRep().getFamily());
enc = (Encounter) obs.getEncounter().getResource();
assertEquals(Encounter.EncounterStatus.ARRIVED, enc.getStatus());
*/
}
@Test
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalLast() {
/*
Observation obs = new Observation();
Patient pt = new Patient();
pt.addName().setFamily("FAM");
obs.getSubject().setResource(pt);
Encounter enc = new Encounter();
enc.setId("#1");
enc.setStatus(Encounter.EncounterStatus.ARRIVED);
obs.getEncounter().setReference("#1");
obs.getContained().add(enc);
String encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(obs);
ourLog.info(encoded);
obs = ourCtx.newRDFParser().parseResource(Observation.class, encoded);
assertEquals("#1", obs.getContained().get(0).getId());
assertEquals("#2", obs.getContained().get(1).getId());
pt = (Patient) obs.getSubject().getResource();
assertEquals("FAM", pt.getNameFirstRep().getFamily());
enc = (Encounter) obs.getEncounter().getResource();
assertEquals(Encounter.EncounterStatus.ARRIVED, enc.getStatus());
*/
}
@Test
public void testEncodeResourceWithMixedManualAndAutomaticContainedResourcesLocalLast2() {
/*
MedicationRequest mr = new MedicationRequest();
Practitioner pract = new Practitioner().setActive(true);
mr.getRequester().setResource(pract);
String encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(mr);
ourLog.info(encoded);
mr = ourCtx.newRDFParser().parseResource(MedicationRequest.class, encoded);
mr.setMedication(new Reference(new Medication().setStatus(Medication.MedicationStatus.ACTIVE)));
encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(mr);
ourLog.info(encoded);
mr = ourCtx.newRDFParser().parseResource(MedicationRequest.class, encoded);
assertEquals("#2", mr.getContained().get(0).getId());
assertEquals("#1", mr.getContained().get(1).getId());
*/
}
@Test
public void testExcludeNothing() {
/*
IParser parser = ourCtx.newRDFParser().setPrettyPrint(true);
Set<String> excludes = new HashSet<>();
// excludes.add("*.id");
parser.setDontEncodeElements(excludes);
Bundle b = createBundleWithPatient();
String encoded = parser.encodeResourceToString(b);
ourLog.info(encoded);
assertThat(encoded, containsString("BUNDLEID"));
assertThat(encoded, containsString("http://FOO"));
assertThat(encoded, containsString("PATIENTID"));
assertThat(encoded, containsString("http://BAR"));
assertThat(encoded, containsString("GIVEN"));
b = parser.parseResource(Bundle.class, encoded);
assertEquals("BUNDLEID", b.getIdElement().getIdPart());
assertEquals("Patient/PATIENTID", b.getEntry().get(0).getResource().getId());
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
*/
}
@Test
@Ignore
public void testExcludeRootStuff() {
/*
IParser parser = ourCtx.newRDFParser().setPrettyPrint(true);
Set<String> excludes = new HashSet<>();
excludes.add("id");
excludes.add("meta");
parser.setDontEncodeElements(excludes);
Bundle b = createBundleWithPatient();
String encoded = parser.encodeResourceToString(b);
ourLog.info(encoded);
assertThat(encoded, not(containsString("BUNDLEID")));
assertThat(encoded, not(containsString("http://FOO")));
assertThat(encoded, (containsString("PATIENTID")));
assertThat(encoded, (containsString("http://BAR")));
assertThat(encoded, containsString("GIVEN"));
b = parser.parseResource(Bundle.class, encoded);
assertNotEquals("BUNDLEID", b.getIdElement().getIdPart());
assertEquals("Patient/PATIENTID", b.getEntry().get(0).getResource().getId());
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
*/
}
@Test
public void testExcludeStarDotStuff() {
/*
IParser parser = ourCtx.newRDFParser().setPrettyPrint(true);
Set<String> excludes = new HashSet<>();
excludes.add("*.id");
excludes.add("*.meta");
parser.setDontEncodeElements(excludes);
Bundle b = createBundleWithPatient();
String encoded = parser.encodeResourceToString(b);
ourLog.info(encoded);
assertThat(encoded, not(containsString("BUNDLEID")));
assertThat(encoded, not(containsString("http://FOO")));
assertThat(encoded, not(containsString("PATIENTID")));
assertThat(encoded, not(containsString("http://BAR")));
assertThat(encoded, containsString("GIVEN"));
b = parser.parseResource(Bundle.class, encoded);
assertNotEquals("BUNDLEID", b.getIdElement().getIdPart());
assertNotEquals("Patient/PATIENTID", b.getEntry().get(0).getResource().getId());
assertEquals("GIVEN", ((Patient) b.getEntry().get(0).getResource()).getNameFirstRep().getGivenAsSingleString());
*/
}
/**
* Test that long JSON strings don't get broken up
*/
@Test
public void testNoBreakInLongString() {
/*
String longString = StringUtils.leftPad("", 100000, 'A');
Patient p = new Patient();
p.addName().setFamily(longString);
String encoded = ourCtx.newRDFParser().setPrettyPrint(true).encodeResourceToString(p);
assertThat(encoded, containsString(longString));
*/
}
@Test
public void testParseAndEncodeExtensionWithValueWithExtension() {
/*
String input = "{\n" +
" \"resourceType\": \"Patient\",\n" +
" \"extension\": [\n" +
" {\n" +
" \"url\": \"https://purl.org/elab/fhir/network/StructureDefinition/1/BirthWeight\",\n" +
" \"_valueDecimal\": {\n" +
" \"extension\": [\n" +
" {\n" +
" \"url\": \"http://www.hl7.org/fhir/extension-data-absent-reason.html\",\n" +
" \"valueCoding\": {\n" +
" \"system\": \"http://hl7.org/fhir/ValueSet/birthweight\",\n" +
" \"code\": \"Underweight\",\n" +
" \"userSelected\": false\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ],\n" +
" \"identifier\": [\n" +
" {\n" +
" \"system\": \"https://purl.org/elab/fhir/network/StructureDefinition/1/EuroPrevallStudySubjects\",\n" +
" \"value\": \"1\"\n" +
" }\n" +
" ],\n" +
" \"gender\": \"female\"\n" +
"}";
IParser jsonParser = ourCtx.newRDFParser();
IParser xmlParser = ourCtx.newXmlParser();
jsonParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
xmlParser.setDontEncodeElements(Sets.newHashSet("id", "meta"));
Patient parsed = jsonParser.parseResource(Patient.class, input);
ourLog.info(jsonParser.setPrettyPrint(true).encodeResourceToString(parsed));
assertThat(xmlParser.encodeResourceToString(parsed), containsString("Underweight"));
assertThat(jsonParser.encodeResourceToString(parsed), containsString("Underweight"));
*/
}
@Test
public void testParseExtensionOnPrimitive() throws IOException {
/*
String input = IOUtils.toString(JsonParserR4Test.class.getResourceAsStream("/extension-on-line.txt"), Constants.CHARSET_UTF8);
IParser parser = ourCtx.newRDFParser().setPrettyPrint(true);
Patient pt = parser.parseResource(Patient.class, input);
StringType line0 = pt.getAddressFirstRep().getLine().get(0);
assertEquals("535 Sheppard Avenue West, Unit 1907", line0.getValue());
Extension houseNumberExt = line0.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-houseNumber");
assertEquals("535", ((StringType) houseNumberExt.getValue()).getValue());
*/
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -0,0 +1,59 @@
package ca.uhn.fhir.parser;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.json.*;
import org.junit.Test;
import org.hl7.fhir.r4.model.*;
import java.io.StringReader;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class RDFParserTest {
private static FhirContext ourCtx = FhirContext.forR4();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RDFParserTest.class);
private static final String TEST_STRUCTURELOADING_DATA =
"{" +
" \"resourceType\":\"Organization\"," +
" \"id\":\"11111\"," +
" \"meta\":{" +
" \"lastUpdated\":\"3900-09-20T10:10:10.000-07:00\"" +
" }," +
" \"identifier\":[" +
" {" +
" \"value\":\"15250\"" +
" }" +
" ]," +
" \"type\":{" +
" \"coding\":[" +
" {" +
" \"system\":\"http://test\"," +
" \"code\":\"ins\"," +
" \"display\":\"General Ledger System\"," +
" \"userSelected\":false" +
" }" +
" ]" +
" }," +
" \"name\":\"Acme Investments\"" +
"}";
@Test
public void testDontStripVersions() {
FhirContext ctx = FhirContext.forR4();
ctx.getParserOptions().setDontStripVersionsFromReferencesAtPaths("QuestionnaireResponse.questionnaire");
//QuestionnaireResponse qr = new QuestionnaireResponse();
//qr.getQuestionnaireElement().setValueAsString("Questionnaire/123/_history/456");
//String output = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(qr);
//ourLog.info(output);
//assertThat(output, containsString("\"Questionnaire/123/_history/456\""));
}
}

View File

@ -937,6 +937,11 @@
<artifactId>httpcore</artifactId> <artifactId>httpcore</artifactId>
<version>${httpcore_version}</version> <version>${httpcore_version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>apache-jena-libs</artifactId>
<version>3.11.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.lucene</groupId> <groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId> <artifactId>lucene-highlighter</artifactId>