Test Classes
This commit is contained in:
parent
e58224e63b
commit
3b35e6add4
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 © 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
pom.xml
5
pom.xml
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue