Implement Jackson parser/serializer (#1733)
* [dev] Integration of a Jackson serializer and deserializer - first stage * [fix] Fixed some serializing issues [improve] Improved the processing, removed the loggers * [clean] Removed the JacksonSerializer class, replaced all the Gson classes with Jackson classes * [clean] Small cleanup * [improve] Throw a ConfigurationException if the JsonGenerator cannot be created * [improve] Use the ObjectMapper's `readTree` instead of `readValue` * [dev] Latest fixes and improvements * [dev] Use the Jackson serializer * [clean] Removed the ObjectMapper configuration, for now * [fix] Use the GsonStructure also for the parsing of a FHIR resource * [clean] Removed the LinkedList usage * Work on preparing for merge of #1673 * Resolve build errors * Work on parser integration * Tests passing * Resolve fixme * CLeanup * Fix dependency Co-authored-by: Bogdan Solga <bogdan.solga@gmail.com>
This commit is contained in:
parent
4583cb9939
commit
bde7c356fe
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
<!-- JSON -->
|
<!-- JSON -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- XML -->
|
<!-- XML -->
|
||||||
|
|
|
@ -22,20 +22,29 @@ package ca.uhn.fhir.parser;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.*;
|
import ca.uhn.fhir.context.*;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
||||||
import ca.uhn.fhir.model.api.*;
|
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||||
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
|
import ca.uhn.fhir.model.api.Tag;
|
||||||
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||||
import ca.uhn.fhir.parser.json.*;
|
import ca.uhn.fhir.parser.json.JsonLikeArray;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeObject;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeValue;
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeWriter;
|
||||||
|
import ca.uhn.fhir.parser.json.jackson.JacksonStructure;
|
||||||
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 com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.text.WordUtils;
|
import org.apache.commons.text.WordUtils;
|
||||||
|
@ -45,11 +54,17 @@ import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.ID_DATATYPE;
|
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.ID_DATATYPE;
|
||||||
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.PRIMITIVE_DATATYPE;
|
import static ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum.PRIMITIVE_DATATYPE;
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use
|
* This class is the FHIR JSON parser/encoder. Users should not interact with this class directly, but should use
|
||||||
|
@ -147,10 +162,9 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
theEventWriter.beginObject(arrayName);
|
theEventWriter.beginObject(arrayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonLikeWriter createJsonWriter(Writer theWriter) {
|
private JsonLikeWriter createJsonWriter(Writer theWriter) throws IOException {
|
||||||
JsonLikeStructure jsonStructure = new GsonStructure();
|
JsonLikeStructure jsonStructure = new JacksonStructure();
|
||||||
JsonLikeWriter retVal = jsonStructure.getJsonLikeWriter(theWriter);
|
return jsonStructure.getJsonLikeWriter(theWriter);
|
||||||
return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doEncodeResourceToJsonLikeWriter(IBaseResource theResource, JsonLikeWriter theEventWriter, EncodeContext theEncodeContext) throws IOException {
|
public void doEncodeResourceToJsonLikeWriter(IBaseResource theResource, JsonLikeWriter theEventWriter, EncodeContext theEncodeContext) throws IOException {
|
||||||
|
@ -168,11 +182,12 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
protected void doEncodeResourceToWriter(IBaseResource theResource, Writer theWriter, EncodeContext theEncodeContext) throws IOException {
|
protected void doEncodeResourceToWriter(IBaseResource theResource, Writer theWriter, EncodeContext theEncodeContext) throws IOException {
|
||||||
JsonLikeWriter eventWriter = createJsonWriter(theWriter);
|
JsonLikeWriter eventWriter = createJsonWriter(theWriter);
|
||||||
doEncodeResourceToJsonLikeWriter(theResource, eventWriter, theEncodeContext);
|
doEncodeResourceToJsonLikeWriter(theResource, eventWriter, theEncodeContext);
|
||||||
|
eventWriter.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) {
|
public <T extends IBaseResource> T doParseResource(Class<T> theResourceType, Reader theReader) {
|
||||||
JsonLikeStructure jsonStructure = new GsonStructure();
|
JsonLikeStructure jsonStructure = new JacksonStructure();
|
||||||
jsonStructure.load(theReader);
|
jsonStructure.load(theReader);
|
||||||
|
|
||||||
T retVal = doParseResource(theResourceType, jsonStructure);
|
T retVal = doParseResource(theResourceType, jsonStructure);
|
||||||
|
@ -418,10 +433,10 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
String currentChildName = null;
|
String currentChildName = null;
|
||||||
boolean inArray = false;
|
boolean inArray = false;
|
||||||
|
|
||||||
ArrayList<ArrayList<HeldExtension>> extensions = new ArrayList<ArrayList<HeldExtension>>(0);
|
ArrayList<ArrayList<HeldExtension>> extensions = new ArrayList<>(0);
|
||||||
ArrayList<ArrayList<HeldExtension>> modifierExtensions = new ArrayList<ArrayList<HeldExtension>>(0);
|
ArrayList<ArrayList<HeldExtension>> modifierExtensions = new ArrayList<>(0);
|
||||||
ArrayList<ArrayList<String>> comments = new ArrayList<ArrayList<String>>(0);
|
ArrayList<ArrayList<String>> comments = new ArrayList<>(0);
|
||||||
ArrayList<String> ids = new ArrayList<String>(0);
|
ArrayList<String> ids = new ArrayList<>(0);
|
||||||
|
|
||||||
int valueIdx = 0;
|
int valueIdx = 0;
|
||||||
for (IBase nextValue : values) {
|
for (IBase nextValue : values) {
|
||||||
|
@ -1107,7 +1122,8 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
} else {
|
} else {
|
||||||
// must be a SCALAR
|
// must be a SCALAR
|
||||||
theState.enteringNewElement(null, theName);
|
theState.enteringNewElement(null, theName);
|
||||||
theState.attributeValue("value", theJsonVal.getAsString());
|
String asString = theJsonVal.getAsString();
|
||||||
|
theState.attributeValue("value", asString);
|
||||||
parseAlternates(theAlternateVal, theState, theAlternateName, theAlternateName);
|
parseAlternates(theAlternateVal, theState, theAlternateName, theAlternateName);
|
||||||
theState.endingElement();
|
theState.endingElement();
|
||||||
}
|
}
|
||||||
|
@ -1376,11 +1392,6 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Gson newGson() {
|
|
||||||
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
|
||||||
return gson;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void write(JsonLikeWriter theWriter, String theName, String theValue) throws IOException {
|
private static void write(JsonLikeWriter theWriter, String theName, String theValue) throws IOException {
|
||||||
theWriter.write(theName, theValue);
|
theWriter.write(theName, theValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,379 +0,0 @@
|
||||||
package ca.uhn.fhir.parser.json;
|
|
||||||
/*
|
|
||||||
* #%L
|
|
||||||
* HAPI FHIR - Core Library
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2014 - 2020 University Health Network
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.io.PushbackReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.util.AbstractSet;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
|
|
||||||
public class GsonStructure implements JsonLikeStructure {
|
|
||||||
|
|
||||||
private enum ROOT_TYPE {OBJECT, ARRAY};
|
|
||||||
private ROOT_TYPE rootType = null;
|
|
||||||
private JsonElement nativeRoot = null;
|
|
||||||
private JsonLikeValue jsonLikeRoot = null;
|
|
||||||
private GsonWriter jsonLikeWriter = null;
|
|
||||||
|
|
||||||
public GsonStructure() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNativeObject (JsonObject json) {
|
|
||||||
this.rootType = ROOT_TYPE.OBJECT;
|
|
||||||
this.nativeRoot = json;
|
|
||||||
}
|
|
||||||
public void setNativeArray (JsonArray json) {
|
|
||||||
this.rootType = ROOT_TYPE.ARRAY;
|
|
||||||
this.nativeRoot = json;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeStructure getInstance() {
|
|
||||||
return new GsonStructure();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Reader theReader) throws DataFormatException {
|
|
||||||
this.load(theReader, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Reader theReader, boolean allowArray) throws DataFormatException {
|
|
||||||
PushbackReader pbr = new PushbackReader(theReader);
|
|
||||||
int nextInt;
|
|
||||||
try {
|
|
||||||
while(true) {
|
|
||||||
nextInt = pbr.read();
|
|
||||||
if (nextInt == -1) {
|
|
||||||
throw new DataFormatException("Did not find any content to parse");
|
|
||||||
}
|
|
||||||
if (nextInt == '{') {
|
|
||||||
pbr.unread(nextInt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (Character.isWhitespace(nextInt)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (allowArray) {
|
|
||||||
if (nextInt == '[') {
|
|
||||||
pbr.unread(nextInt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
throw new DataFormatException("Content does not appear to be FHIR JSON, first non-whitespace character was: '" + (char)nextInt + "' (must be '{' or '[')");
|
|
||||||
}
|
|
||||||
throw new DataFormatException("Content does not appear to be FHIR JSON, first non-whitespace character was: '" + (char)nextInt + "' (must be '{')");
|
|
||||||
}
|
|
||||||
|
|
||||||
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
|
||||||
if (nextInt == '{') {
|
|
||||||
JsonObject root = gson.fromJson(pbr, JsonObject.class);
|
|
||||||
setNativeObject(root);
|
|
||||||
} else if (nextInt == '[') {
|
|
||||||
JsonArray root = gson.fromJson(pbr, JsonArray.class);
|
|
||||||
setNativeArray(root);
|
|
||||||
}
|
|
||||||
} catch (JsonSyntaxException e) {
|
|
||||||
if (e.getMessage().startsWith("Unexpected char 39")) {
|
|
||||||
throw new DataFormatException("Failed to parse JSON encoded FHIR content: " + e.getMessage() + " - This may indicate that single quotes are being used as JSON escapes where double quotes are required", e);
|
|
||||||
}
|
|
||||||
throw new DataFormatException("Failed to parse JSON encoded FHIR content: " + e.getMessage(), e);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new DataFormatException("Failed to parse JSON content, error was: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter getJsonLikeWriter (Writer writer) {
|
|
||||||
if (null == jsonLikeWriter) {
|
|
||||||
jsonLikeWriter = new GsonWriter(writer);
|
|
||||||
}
|
|
||||||
return jsonLikeWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter getJsonLikeWriter () {
|
|
||||||
if (null == jsonLikeWriter) {
|
|
||||||
jsonLikeWriter = new GsonWriter();
|
|
||||||
}
|
|
||||||
return jsonLikeWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeObject getRootObject() throws DataFormatException {
|
|
||||||
if (rootType == ROOT_TYPE.OBJECT) {
|
|
||||||
if (null == jsonLikeRoot) {
|
|
||||||
jsonLikeRoot = new GsonJsonObject((JsonObject)nativeRoot);
|
|
||||||
}
|
|
||||||
return jsonLikeRoot.getAsObject();
|
|
||||||
}
|
|
||||||
throw new DataFormatException("Content must be a valid JSON Object. It must start with '{'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeArray getRootArray() throws DataFormatException {
|
|
||||||
if (rootType == ROOT_TYPE.ARRAY) {
|
|
||||||
if (null == jsonLikeRoot) {
|
|
||||||
jsonLikeRoot = new GsonJsonArray((JsonArray)nativeRoot);
|
|
||||||
}
|
|
||||||
return jsonLikeRoot.getAsArray();
|
|
||||||
}
|
|
||||||
throw new DataFormatException("Content must be a valid JSON Array. It must start with '['.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GsonJsonObject extends JsonLikeObject {
|
|
||||||
private JsonObject nativeObject;
|
|
||||||
private Set<String> keySet = null;
|
|
||||||
private Map<String,JsonLikeValue> jsonLikeMap = new LinkedHashMap<String,JsonLikeValue>();
|
|
||||||
|
|
||||||
public GsonJsonObject (JsonObject json) {
|
|
||||||
this.nativeObject = json;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValue() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> keySet() {
|
|
||||||
if (null == keySet) {
|
|
||||||
Set<Entry<String, JsonElement>> entrySet = nativeObject.entrySet();
|
|
||||||
keySet = new EntryOrderedSet<String>(entrySet.size());
|
|
||||||
for (Entry<String,?> entry : entrySet) {
|
|
||||||
keySet.add(entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keySet;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeValue get(String key) {
|
|
||||||
JsonLikeValue result = null;
|
|
||||||
if (jsonLikeMap.containsKey(key)) {
|
|
||||||
result = jsonLikeMap.get(key);
|
|
||||||
} else {
|
|
||||||
JsonElement child = nativeObject.get(key);
|
|
||||||
if (child != null) {
|
|
||||||
result = new GsonJsonValue(child);
|
|
||||||
}
|
|
||||||
jsonLikeMap.put(key, result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GsonJsonArray extends JsonLikeArray {
|
|
||||||
private JsonArray nativeArray;
|
|
||||||
private Map<Integer,JsonLikeValue> jsonLikeMap = new LinkedHashMap<Integer,JsonLikeValue>();
|
|
||||||
|
|
||||||
public GsonJsonArray (JsonArray json) {
|
|
||||||
this.nativeArray = json;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValue() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return nativeArray.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeValue get(int index) {
|
|
||||||
Integer key = Integer.valueOf(index);
|
|
||||||
JsonLikeValue result = null;
|
|
||||||
if (jsonLikeMap.containsKey(key)) {
|
|
||||||
result = jsonLikeMap.get(key);
|
|
||||||
} else {
|
|
||||||
JsonElement child = nativeArray.get(index);
|
|
||||||
if (child != null) {
|
|
||||||
result = new GsonJsonValue(child);
|
|
||||||
}
|
|
||||||
jsonLikeMap.put(key, result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GsonJsonValue extends JsonLikeValue {
|
|
||||||
private JsonElement nativeValue;
|
|
||||||
private JsonLikeObject jsonLikeObject = null;
|
|
||||||
private JsonLikeArray jsonLikeArray = null;
|
|
||||||
|
|
||||||
public GsonJsonValue (JsonElement json) {
|
|
||||||
this.nativeValue = json;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValue() {
|
|
||||||
if (nativeValue != null && nativeValue.isJsonPrimitive()) {
|
|
||||||
if (((JsonPrimitive)nativeValue).isNumber()) {
|
|
||||||
return nativeValue.getAsNumber();
|
|
||||||
}
|
|
||||||
if (((JsonPrimitive)nativeValue).isBoolean()) {
|
|
||||||
return Boolean.valueOf(nativeValue.getAsBoolean());
|
|
||||||
}
|
|
||||||
return nativeValue.getAsString();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ValueType getJsonType() {
|
|
||||||
if (null == nativeValue || nativeValue.isJsonNull()) {
|
|
||||||
return ValueType.NULL;
|
|
||||||
}
|
|
||||||
if (nativeValue.isJsonObject()) {
|
|
||||||
return ValueType.OBJECT;
|
|
||||||
}
|
|
||||||
if (nativeValue.isJsonArray()) {
|
|
||||||
return ValueType.ARRAY;
|
|
||||||
}
|
|
||||||
if (nativeValue.isJsonPrimitive()) {
|
|
||||||
return ValueType.SCALAR;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ScalarType getDataType() {
|
|
||||||
if (nativeValue != null && nativeValue.isJsonPrimitive()) {
|
|
||||||
if (((JsonPrimitive)nativeValue).isNumber()) {
|
|
||||||
return ScalarType.NUMBER;
|
|
||||||
}
|
|
||||||
if (((JsonPrimitive)nativeValue).isString()) {
|
|
||||||
return ScalarType.STRING;
|
|
||||||
}
|
|
||||||
if (((JsonPrimitive)nativeValue).isBoolean()) {
|
|
||||||
return ScalarType.BOOLEAN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeArray getAsArray() {
|
|
||||||
if (nativeValue != null && nativeValue.isJsonArray()) {
|
|
||||||
if (null == jsonLikeArray) {
|
|
||||||
jsonLikeArray = new GsonJsonArray((JsonArray)nativeValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return jsonLikeArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeObject getAsObject() {
|
|
||||||
if (nativeValue != null && nativeValue.isJsonObject()) {
|
|
||||||
if (null == jsonLikeObject) {
|
|
||||||
jsonLikeObject = new GsonJsonObject((JsonObject)nativeValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return jsonLikeObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Number getAsNumber() {
|
|
||||||
return nativeValue != null ? nativeValue.getAsNumber() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAsString() {
|
|
||||||
return nativeValue != null ? nativeValue.getAsString() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getAsBoolean() {
|
|
||||||
if (nativeValue != null && nativeValue.isJsonPrimitive() && ((JsonPrimitive)nativeValue).isBoolean()) {
|
|
||||||
return nativeValue.getAsBoolean();
|
|
||||||
}
|
|
||||||
return super.getAsBoolean();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class EntryOrderedSet<T> extends AbstractSet<T> {
|
|
||||||
private transient ArrayList<T> data = null;
|
|
||||||
|
|
||||||
public EntryOrderedSet (int initialCapacity) {
|
|
||||||
data = new ArrayList<T>(initialCapacity);
|
|
||||||
}
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public EntryOrderedSet () {
|
|
||||||
data = new ArrayList<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(Object o) {
|
|
||||||
return data.contains(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused") // not really.. just not here
|
|
||||||
public T get(int index) {
|
|
||||||
return data.get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(T element) {
|
|
||||||
if (data.contains(element)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return data.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean remove(Object o) {
|
|
||||||
return data.remove(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<T> iterator() {
|
|
||||||
return data.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,263 +0,0 @@
|
||||||
package ca.uhn.fhir.parser.json;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* #%L
|
|
||||||
* HAPI FHIR - Core Library
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2014 - 2020 University Health Network
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
|
|
||||||
public class GsonWriter extends JsonLikeWriter {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(GsonWriter.class);
|
|
||||||
|
|
||||||
private JsonWriter eventWriter;
|
|
||||||
private enum BlockType {
|
|
||||||
NONE, OBJECT, ARRAY
|
|
||||||
}
|
|
||||||
private BlockType blockType = BlockType.NONE;
|
|
||||||
private Stack<BlockType> blockStack = new Stack<BlockType>();
|
|
||||||
|
|
||||||
public GsonWriter () {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
public GsonWriter (Writer writer) {
|
|
||||||
setWriter(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter init() throws IOException {
|
|
||||||
eventWriter = new JsonWriter(getWriter());
|
|
||||||
eventWriter.setSerializeNulls(true);
|
|
||||||
if (isPrettyPrint()) {
|
|
||||||
eventWriter.setIndent(" ");
|
|
||||||
}
|
|
||||||
blockType = BlockType.NONE;
|
|
||||||
blockStack.clear();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter flush() throws IOException {
|
|
||||||
if (blockType != BlockType.NONE) {
|
|
||||||
log.error("JsonLikeStreamWriter.flush() called but JSON document is not finished");
|
|
||||||
}
|
|
||||||
eventWriter.flush();
|
|
||||||
getWriter().flush();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
eventWriter.close();
|
|
||||||
getWriter().close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter beginObject() throws IOException {
|
|
||||||
blockStack.push(blockType);
|
|
||||||
blockType = BlockType.OBJECT;
|
|
||||||
eventWriter.beginObject();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter beginArray() throws IOException {
|
|
||||||
blockStack.push(blockType);
|
|
||||||
blockType = BlockType.ARRAY;
|
|
||||||
eventWriter.beginArray();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter beginObject(String name) throws IOException {
|
|
||||||
blockStack.push(blockType);
|
|
||||||
blockType = BlockType.OBJECT;
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.beginObject();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter beginArray(String name) throws IOException {
|
|
||||||
blockStack.push(blockType);
|
|
||||||
blockType = BlockType.ARRAY;
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.beginArray();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String value) throws IOException {
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(BigInteger value) throws IOException {
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(BigDecimal value) throws IOException {
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(long value) throws IOException {
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(double value) throws IOException {
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(Boolean value) throws IOException {
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(boolean value) throws IOException {
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter writeNull() throws IOException {
|
|
||||||
eventWriter.nullValue();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String name, String value) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String name, BigInteger value) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String name, BigDecimal value) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String name, long value) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String name, double value) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String name, Boolean value) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter write(String name, boolean value) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.value(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter writeNull(String name) throws IOException {
|
|
||||||
eventWriter.name(name);
|
|
||||||
eventWriter.nullValue();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter endObject() throws IOException {
|
|
||||||
if (blockType == BlockType.NONE) {
|
|
||||||
log.error("JsonLikeStreamWriter.endObject(); called with no active JSON document");
|
|
||||||
} else {
|
|
||||||
if (blockType != BlockType.OBJECT) {
|
|
||||||
log.error("JsonLikeStreamWriter.endObject(); called outside a JSON object. (Use endArray() instead?)");
|
|
||||||
eventWriter.endArray();
|
|
||||||
} else {
|
|
||||||
eventWriter.endObject();
|
|
||||||
}
|
|
||||||
blockType = blockStack.pop();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter endArray() throws IOException {
|
|
||||||
if (blockType == BlockType.NONE) {
|
|
||||||
log.error("JsonLikeStreamWriter.endArray(); called with no active JSON document");
|
|
||||||
} else {
|
|
||||||
if (blockType != BlockType.ARRAY) {
|
|
||||||
log.error("JsonLikeStreamWriter.endArray(); called outside a JSON array. (Use endObject() instead?)");
|
|
||||||
eventWriter.endObject();
|
|
||||||
} else {
|
|
||||||
eventWriter.endArray();
|
|
||||||
}
|
|
||||||
blockType = blockStack.pop();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter endBlock() throws IOException {
|
|
||||||
if (blockType == BlockType.NONE) {
|
|
||||||
log.error("JsonLikeStreamWriter.endBlock(); called with no active JSON document");
|
|
||||||
} else {
|
|
||||||
if (blockType == BlockType.ARRAY) {
|
|
||||||
eventWriter.endArray();
|
|
||||||
} else {
|
|
||||||
eventWriter.endObject();
|
|
||||||
}
|
|
||||||
blockType = blockStack.pop();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -53,20 +53,4 @@ public abstract class JsonLikeObject extends JsonLikeValue {
|
||||||
|
|
||||||
public abstract JsonLikeValue get (String key);
|
public abstract JsonLikeValue get (String key);
|
||||||
|
|
||||||
public String getString (String key) {
|
|
||||||
JsonLikeValue value = this.get(key);
|
|
||||||
if (null == value) {
|
|
||||||
throw new NullPointerException("Json object missing element named \""+key+"\"");
|
|
||||||
}
|
|
||||||
return value.getAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getString (String key, String defaultValue) {
|
|
||||||
String result = defaultValue;
|
|
||||||
JsonLikeValue value = this.get(key);
|
|
||||||
if (value != null) {
|
|
||||||
result = value.getAsString();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,12 @@
|
||||||
*/
|
*/
|
||||||
package ca.uhn.fhir.parser.json;
|
package ca.uhn.fhir.parser.json;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface is the generic representation of any sort of data
|
* This interface is the generic representation of any sort of data
|
||||||
* structure that looks and smells like JSON. These data structures
|
* structure that looks and smells like JSON. These data structures
|
||||||
|
@ -33,7 +34,7 @@ import ca.uhn.fhir.parser.DataFormatException;
|
||||||
* @author Bill.Denton
|
* @author Bill.Denton
|
||||||
*/
|
*/
|
||||||
public interface JsonLikeStructure {
|
public interface JsonLikeStructure {
|
||||||
public JsonLikeStructure getInstance();
|
JsonLikeStructure getInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the JSON document into the Json-like structure
|
* Parse the JSON document into the Json-like structure
|
||||||
|
@ -43,10 +44,13 @@ public interface JsonLikeStructure {
|
||||||
* process the JSON input stream
|
* process the JSON input stream
|
||||||
* @throws DataFormatException when invalid JSON is received
|
* @throws DataFormatException when invalid JSON is received
|
||||||
*/
|
*/
|
||||||
public void load (Reader theReader) throws DataFormatException;
|
void load(Reader theReader) throws DataFormatException;
|
||||||
public void load (Reader theReader, boolean allowArray) throws DataFormatException;
|
|
||||||
public JsonLikeObject getRootObject () throws DataFormatException;
|
void load(Reader theReader, boolean allowArray) throws DataFormatException;
|
||||||
public JsonLikeArray getRootArray () throws DataFormatException;
|
|
||||||
public JsonLikeWriter getJsonLikeWriter ();
|
JsonLikeObject getRootObject() throws DataFormatException;
|
||||||
public JsonLikeWriter getJsonLikeWriter (Writer writer);
|
|
||||||
|
JsonLikeWriter getJsonLikeWriter();
|
||||||
|
|
||||||
|
JsonLikeWriter getJsonLikeWriter(Writer writer) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,54 +30,72 @@ public abstract class JsonLikeWriter {
|
||||||
private boolean prettyPrint;
|
private boolean prettyPrint;
|
||||||
private Writer writer;
|
private Writer writer;
|
||||||
|
|
||||||
|
public JsonLikeWriter() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPrettyPrint() {
|
||||||
|
return prettyPrint;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPrettyPrint(boolean tf) {
|
public void setPrettyPrint(boolean tf) {
|
||||||
prettyPrint = tf;
|
prettyPrint = tf;
|
||||||
}
|
}
|
||||||
public boolean isPrettyPrint () {
|
|
||||||
return prettyPrint;
|
public Writer getWriter() {
|
||||||
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWriter(Writer writer) {
|
public void setWriter(Writer writer) {
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
}
|
}
|
||||||
public Writer getWriter () {
|
|
||||||
return writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract JsonLikeWriter init() throws IOException;
|
public abstract JsonLikeWriter init() throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter flush() throws IOException;
|
public abstract JsonLikeWriter flush() throws IOException;
|
||||||
|
|
||||||
public abstract void close() throws IOException;
|
public abstract void close() throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter beginObject() throws IOException;
|
public abstract JsonLikeWriter beginObject() throws IOException;
|
||||||
public abstract JsonLikeWriter beginArray () throws IOException;
|
|
||||||
|
|
||||||
public abstract JsonLikeWriter beginObject(String name) throws IOException;
|
public abstract JsonLikeWriter beginObject(String name) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter beginArray(String name) throws IOException;
|
public abstract JsonLikeWriter beginArray(String name) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String value) throws IOException;
|
public abstract JsonLikeWriter write(String value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(BigInteger value) throws IOException;
|
public abstract JsonLikeWriter write(BigInteger value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(BigDecimal value) throws IOException;
|
public abstract JsonLikeWriter write(BigDecimal value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(long value) throws IOException;
|
public abstract JsonLikeWriter write(long value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(double value) throws IOException;
|
public abstract JsonLikeWriter write(double value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(Boolean value) throws IOException;
|
public abstract JsonLikeWriter write(Boolean value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(boolean value) throws IOException;
|
public abstract JsonLikeWriter write(boolean value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter writeNull() throws IOException;
|
public abstract JsonLikeWriter writeNull() throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String name, String value) throws IOException;
|
public abstract JsonLikeWriter write(String name, String value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String name, BigInteger value) throws IOException;
|
public abstract JsonLikeWriter write(String name, BigInteger value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String name, BigDecimal value) throws IOException;
|
public abstract JsonLikeWriter write(String name, BigDecimal value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String name, long value) throws IOException;
|
public abstract JsonLikeWriter write(String name, long value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String name, double value) throws IOException;
|
public abstract JsonLikeWriter write(String name, double value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String name, Boolean value) throws IOException;
|
public abstract JsonLikeWriter write(String name, Boolean value) throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter write(String name, boolean value) throws IOException;
|
public abstract JsonLikeWriter write(String name, boolean value) throws IOException;
|
||||||
public abstract JsonLikeWriter writeNull (String name) throws IOException;
|
|
||||||
|
|
||||||
public abstract JsonLikeWriter endObject() throws IOException;
|
public abstract JsonLikeWriter endObject() throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter endArray() throws IOException;
|
public abstract JsonLikeWriter endArray() throws IOException;
|
||||||
|
|
||||||
public abstract JsonLikeWriter endBlock() throws IOException;
|
public abstract JsonLikeWriter endBlock() throws IOException;
|
||||||
|
|
||||||
public JsonLikeWriter() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,372 @@
|
||||||
|
package ca.uhn.fhir.parser.json.jackson;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeArray;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeObject;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeValue;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeWriter;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.DecimalNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import org.apache.jena.tdb.setup.BuilderStdDB;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PushbackReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.AbstractSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
public class JacksonStructure implements JsonLikeStructure {
|
||||||
|
|
||||||
|
private static final ObjectMapper OBJECT_MAPPER = createObjectMapper();
|
||||||
|
private JacksonWriter jacksonWriter;
|
||||||
|
private ROOT_TYPE rootType = null;
|
||||||
|
private JsonNode nativeRoot = null;
|
||||||
|
private JsonNode jsonLikeRoot = null;
|
||||||
|
|
||||||
|
public void setNativeObject(ObjectNode objectNode) {
|
||||||
|
this.rootType = ROOT_TYPE.OBJECT;
|
||||||
|
this.nativeRoot = objectNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNativeArray(ArrayNode arrayNode) {
|
||||||
|
this.rootType = ROOT_TYPE.ARRAY;
|
||||||
|
this.nativeRoot = arrayNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeStructure getInstance() {
|
||||||
|
return new JacksonStructure();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Reader theReader) throws DataFormatException {
|
||||||
|
this.load(theReader, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Reader theReader, boolean allowArray) throws DataFormatException {
|
||||||
|
PushbackReader pbr = new PushbackReader(theReader);
|
||||||
|
int nextInt;
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
nextInt = pbr.read();
|
||||||
|
if (nextInt == -1) {
|
||||||
|
throw new DataFormatException("Did not find any content to parse");
|
||||||
|
}
|
||||||
|
if (nextInt == '{') {
|
||||||
|
pbr.unread(nextInt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (Character.isWhitespace(nextInt)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (allowArray) {
|
||||||
|
if (nextInt == '[') {
|
||||||
|
pbr.unread(nextInt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw new DataFormatException("Content does not appear to be FHIR JSON, first non-whitespace character was: '" + (char) nextInt + "' (must be '{' or '[')");
|
||||||
|
}
|
||||||
|
throw new DataFormatException("Content does not appear to be FHIR JSON, first non-whitespace character was: '" + (char) nextInt + "' (must be '{')");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextInt == '{') {
|
||||||
|
setNativeObject((ObjectNode) OBJECT_MAPPER.readTree(pbr));
|
||||||
|
} else {
|
||||||
|
setNativeArray((ArrayNode) OBJECT_MAPPER.readTree(pbr));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e.getMessage().startsWith("Unexpected char 39")) {
|
||||||
|
throw new DataFormatException("Failed to parse JSON encoded FHIR content: " + e.getMessage() + " - " +
|
||||||
|
"This may indicate that single quotes are being used as JSON escapes where double quotes are required", e);
|
||||||
|
}
|
||||||
|
throw new DataFormatException("Failed to parse JSON encoded FHIR content: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter getJsonLikeWriter(Writer writer) throws IOException {
|
||||||
|
if (null == jacksonWriter) {
|
||||||
|
jacksonWriter = new JacksonWriter(OBJECT_MAPPER.getFactory(), writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jacksonWriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter getJsonLikeWriter() {
|
||||||
|
if (null == jacksonWriter) {
|
||||||
|
jacksonWriter = new JacksonWriter();
|
||||||
|
}
|
||||||
|
return jacksonWriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeObject getRootObject() throws DataFormatException {
|
||||||
|
if (rootType == ROOT_TYPE.OBJECT) {
|
||||||
|
if (null == jsonLikeRoot) {
|
||||||
|
jsonLikeRoot = nativeRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JacksonJsonObject((ObjectNode) jsonLikeRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new DataFormatException("Content must be a valid JSON Object. It must start with '{'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ROOT_TYPE {OBJECT, ARRAY}
|
||||||
|
|
||||||
|
private static class JacksonJsonObject extends JsonLikeObject {
|
||||||
|
private final ObjectNode nativeObject;
|
||||||
|
private final Map<String, JsonLikeValue> jsonLikeMap = new LinkedHashMap<>();
|
||||||
|
private Set<String> keySet = null;
|
||||||
|
|
||||||
|
public JacksonJsonObject(ObjectNode json) {
|
||||||
|
this.nativeObject = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> keySet() {
|
||||||
|
if (null == keySet) {
|
||||||
|
final Iterable<Map.Entry<String, JsonNode>> iterable = nativeObject::fields;
|
||||||
|
keySet = StreamSupport.stream(iterable.spliterator(), false)
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.collect(Collectors.toCollection(EntryOrderedSet::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
return keySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeValue get(String key) {
|
||||||
|
JsonLikeValue result = null;
|
||||||
|
if (jsonLikeMap.containsKey(key)) {
|
||||||
|
result = jsonLikeMap.get(key);
|
||||||
|
} else {
|
||||||
|
JsonNode child = nativeObject.get(key);
|
||||||
|
if (child != null) {
|
||||||
|
result = new JacksonJsonValue(child);
|
||||||
|
}
|
||||||
|
jsonLikeMap.put(key, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class EntryOrderedSet<T> extends AbstractSet<T> {
|
||||||
|
private final transient ArrayList<T> data;
|
||||||
|
|
||||||
|
public EntryOrderedSet() {
|
||||||
|
data = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return data.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T get(int index) {
|
||||||
|
return data.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(T element) {
|
||||||
|
if (data.contains(element)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return data.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
return data.remove(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator() {
|
||||||
|
return data.iterator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class JacksonJsonArray extends JsonLikeArray {
|
||||||
|
private final ArrayNode nativeArray;
|
||||||
|
private final Map<Integer, JsonLikeValue> jsonLikeMap = new LinkedHashMap<Integer, JsonLikeValue>();
|
||||||
|
|
||||||
|
public JacksonJsonArray(ArrayNode json) {
|
||||||
|
this.nativeArray = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return nativeArray.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeValue get(int index) {
|
||||||
|
Integer key = index;
|
||||||
|
JsonLikeValue result = null;
|
||||||
|
if (jsonLikeMap.containsKey(key)) {
|
||||||
|
result = jsonLikeMap.get(key);
|
||||||
|
} else {
|
||||||
|
JsonNode child = nativeArray.get(index);
|
||||||
|
if (child != null) {
|
||||||
|
result = new JacksonJsonValue(child);
|
||||||
|
}
|
||||||
|
jsonLikeMap.put(key, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class JacksonJsonValue extends JsonLikeValue {
|
||||||
|
private final JsonNode nativeValue;
|
||||||
|
private JsonLikeObject jsonLikeObject = null;
|
||||||
|
private JsonLikeArray jsonLikeArray = null;
|
||||||
|
|
||||||
|
public JacksonJsonValue(JsonNode jsonNode) {
|
||||||
|
this.nativeValue = jsonNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue() {
|
||||||
|
if (nativeValue != null && nativeValue.isValueNode()) {
|
||||||
|
if (nativeValue.isNumber()) {
|
||||||
|
return nativeValue.numberValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nativeValue.isBoolean()) {
|
||||||
|
return nativeValue.booleanValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nativeValue.asText();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueType getJsonType() {
|
||||||
|
if (null == nativeValue || nativeValue.isNull()) {
|
||||||
|
return ValueType.NULL;
|
||||||
|
}
|
||||||
|
if (nativeValue.isObject()) {
|
||||||
|
return ValueType.OBJECT;
|
||||||
|
}
|
||||||
|
if (nativeValue.isArray()) {
|
||||||
|
return ValueType.ARRAY;
|
||||||
|
}
|
||||||
|
if (nativeValue.isValueNode()) {
|
||||||
|
return ValueType.SCALAR;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScalarType getDataType() {
|
||||||
|
if (nativeValue != null && nativeValue.isValueNode()) {
|
||||||
|
if (nativeValue.isNumber()) {
|
||||||
|
return ScalarType.NUMBER;
|
||||||
|
}
|
||||||
|
if (nativeValue.isTextual()) {
|
||||||
|
return ScalarType.STRING;
|
||||||
|
}
|
||||||
|
if (nativeValue.isBoolean()) {
|
||||||
|
return ScalarType.BOOLEAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeArray getAsArray() {
|
||||||
|
if (nativeValue != null && nativeValue.isArray()) {
|
||||||
|
if (null == jsonLikeArray) {
|
||||||
|
jsonLikeArray = new JacksonJsonArray((ArrayNode) nativeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonLikeArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeObject getAsObject() {
|
||||||
|
if (nativeValue != null && nativeValue.isObject()) {
|
||||||
|
if (null == jsonLikeObject) {
|
||||||
|
jsonLikeObject = new JacksonJsonObject((ObjectNode) nativeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonLikeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Number getAsNumber() {
|
||||||
|
return nativeValue != null ? nativeValue.numberValue() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAsString() {
|
||||||
|
if (nativeValue != null) {
|
||||||
|
if (nativeValue instanceof DecimalNode) {
|
||||||
|
BigDecimal value = nativeValue.decimalValue();
|
||||||
|
return value.toPlainString();
|
||||||
|
}
|
||||||
|
return nativeValue.asText();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getAsBoolean() {
|
||||||
|
if (nativeValue != null && nativeValue.isValueNode() && nativeValue.isBoolean()) {
|
||||||
|
return nativeValue.asBoolean();
|
||||||
|
}
|
||||||
|
return super.getAsBoolean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ObjectMapper createObjectMapper() {
|
||||||
|
ObjectMapper retVal = new ObjectMapper();
|
||||||
|
retVal = retVal.setNodeFactory(new JsonNodeFactory(true));
|
||||||
|
retVal = retVal.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
|
||||||
|
retVal = retVal.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
|
||||||
|
retVal = retVal.disable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION);
|
||||||
|
retVal = retVal.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
|
||||||
|
retVal = retVal.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
|
||||||
|
retVal = retVal.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
package ca.uhn.fhir.parser.json.jackson;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeWriter;
|
||||||
|
import com.fasterxml.jackson.core.JsonFactory;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.PrettyPrinter;
|
||||||
|
import com.fasterxml.jackson.core.util.DefaultIndenter;
|
||||||
|
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||||
|
import com.fasterxml.jackson.core.util.Separators;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class JacksonWriter extends JsonLikeWriter {
|
||||||
|
|
||||||
|
private JsonGenerator myJsonGenerator;
|
||||||
|
|
||||||
|
public JacksonWriter(JsonFactory theJsonFactory, Writer theWriter) throws IOException {
|
||||||
|
myJsonGenerator = theJsonFactory.createGenerator(theWriter);
|
||||||
|
setWriter(theWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JacksonWriter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter init() {
|
||||||
|
if (isPrettyPrint()) {
|
||||||
|
DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Objects should serialize as
|
||||||
|
* <pre>
|
||||||
|
* {
|
||||||
|
* "key": "value"
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* in order to be consistent with Gson behaviour, instead of the jackson default
|
||||||
|
* <pre>
|
||||||
|
* {
|
||||||
|
* "key" : "value"
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DefaultPrettyPrinter withSeparators(Separators separators) {
|
||||||
|
_separators = separators;
|
||||||
|
_objectFieldValueSeparatorWithSpaces = separators.getObjectFieldValueSeparator() + " ";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
prettyPrinter = prettyPrinter.withObjectIndenter(new DefaultIndenter(" ", "\n"));
|
||||||
|
|
||||||
|
myJsonGenerator.setPrettyPrinter(prettyPrinter);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter flush() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
myJsonGenerator.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter beginObject() throws IOException {
|
||||||
|
myJsonGenerator.writeStartObject();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter beginObject(String name) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectFieldStart(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter beginArray(String name) throws IOException {
|
||||||
|
myJsonGenerator.writeArrayFieldStart(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String value) throws IOException {
|
||||||
|
myJsonGenerator.writeObject(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(BigInteger value) throws IOException {
|
||||||
|
myJsonGenerator.writeObject(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(BigDecimal value) throws IOException {
|
||||||
|
myJsonGenerator.writeObject(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(long value) throws IOException {
|
||||||
|
myJsonGenerator.writeObject(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(double value) throws IOException {
|
||||||
|
myJsonGenerator.writeObject(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(Boolean value) throws IOException {
|
||||||
|
myJsonGenerator.writeObject(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(boolean value) throws IOException {
|
||||||
|
myJsonGenerator.writeObject(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter writeNull() throws IOException {
|
||||||
|
myJsonGenerator.writeNull();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String name, String value) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectField(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String name, BigInteger value) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectField(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String name, BigDecimal value) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectField(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String name, long value) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectField(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String name, double value) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectField(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String name, Boolean value) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectField(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter write(String name, boolean value) throws IOException {
|
||||||
|
myJsonGenerator.writeObjectField(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter endObject() throws IOException {
|
||||||
|
myJsonGenerator.writeEndObject();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter endArray() throws IOException {
|
||||||
|
myJsonGenerator.writeEndArray();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonLikeWriter endBlock() throws IOException {
|
||||||
|
myJsonGenerator.writeEndObject();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.parser.json.jackson.JacksonStructure;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class JsonLikeStructureTest {
|
public class JsonLikeStructureTest {
|
||||||
|
@ -39,7 +40,7 @@ public class JsonLikeStructureTest {
|
||||||
@Test
|
@Test
|
||||||
public void testStructureLoading() {
|
public void testStructureLoading() {
|
||||||
StringReader reader = new StringReader(TEST_STRUCTURELOADING_DATA);
|
StringReader reader = new StringReader(TEST_STRUCTURELOADING_DATA);
|
||||||
JsonLikeStructure jsonStructure = new GsonStructure();
|
JsonLikeStructure jsonStructure = new JacksonStructure();
|
||||||
jsonStructure.load(reader);
|
jsonStructure.load(reader);
|
||||||
|
|
||||||
JsonLikeObject rootObject = jsonStructure.getRootObject();
|
JsonLikeObject rootObject = jsonStructure.getRootObject();
|
||||||
|
@ -70,7 +71,7 @@ public class JsonLikeStructureTest {
|
||||||
@Test
|
@Test
|
||||||
public void testJsonAndDataTypes() {
|
public void testJsonAndDataTypes() {
|
||||||
StringReader reader = new StringReader(TEST_JSONTYPES_DATA);
|
StringReader reader = new StringReader(TEST_JSONTYPES_DATA);
|
||||||
JsonLikeStructure jsonStructure = new GsonStructure();
|
JsonLikeStructure jsonStructure = new JacksonStructure();
|
||||||
jsonStructure.load(reader);
|
jsonStructure.load(reader);
|
||||||
|
|
||||||
JsonLikeObject rootObject = jsonStructure.getRootObject();
|
JsonLikeObject rootObject = jsonStructure.getRootObject();
|
||||||
|
|
|
@ -5368,7 +5368,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
@Test
|
@Test
|
||||||
public void testValidateJsonWithDuplicateKey() throws IOException {
|
public void testValidateJsonWithDuplicateKey() throws IOException {
|
||||||
|
|
||||||
String inputStr = "{\"resourceType\":\"Patient\", \"name\":[{\"text\":foo\"}], name:[{\"text\":\"foo\"}] }";
|
String inputStr = "{\"resourceType\":\"Patient\", \"name\":[{\"text\":\"foo\"}], \"name\":[{\"text\":\"foo\"}] }";
|
||||||
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
|
HttpPost post = new HttpPost(ourServerBase + "/Patient/$validate");
|
||||||
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_JSON_NEW, "UTF-8")));
|
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_JSON_NEW, "UTF-8")));
|
||||||
|
|
||||||
|
@ -5378,7 +5378,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
ourLog.info(resp);
|
ourLog.info(resp);
|
||||||
assertEquals(412, response.getStatusLine().getStatusCode());
|
assertEquals(412, response.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
assertThat(resp, stringContainsInOrder("Error parsing JSON source: Syntax error in json reading special word false at Line 1"));
|
assertThat(resp, stringContainsInOrder("Duplicated property name: name"));
|
||||||
} finally {
|
} finally {
|
||||||
response.getEntity().getContent().close();
|
response.getEntity().getContent().close();
|
||||||
response.close();
|
response.close();
|
||||||
|
|
|
@ -1518,13 +1518,13 @@ public class JsonParserDstu2_1Test {
|
||||||
ourCtx.newJsonParser().parseResource("FOO");
|
ourCtx.newJsonParser().parseResource("FOO");
|
||||||
fail();
|
fail();
|
||||||
} catch (DataFormatException e) {
|
} catch (DataFormatException e) {
|
||||||
assertEquals("Failed to parse JSON content, error was: Content does not appear to be FHIR JSON, first non-whitespace character was: 'F' (must be '{')", e.getMessage());
|
assertEquals("Failed to parse JSON encoded FHIR content: Content does not appear to be FHIR JSON, first non-whitespace character was: 'F' (must be '{')", e.getMessage());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ourCtx.newJsonParser().parseResource("[\"aaa\"]");
|
ourCtx.newJsonParser().parseResource("[\"aaa\"]");
|
||||||
fail();
|
fail();
|
||||||
} catch (DataFormatException e) {
|
} catch (DataFormatException e) {
|
||||||
assertEquals("Failed to parse JSON content, error was: Content does not appear to be FHIR JSON, first non-whitespace character was: '[' (must be '{')", e.getMessage());
|
assertEquals("Failed to parse JSON encoded FHIR content: Content does not appear to be FHIR JSON, first non-whitespace character was: '[' (must be '{')", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(Bundle.class, ourCtx.newJsonParser().parseResource(" {\"resourceType\" : \"Bundle\"}").getClass());
|
assertEquals(Bundle.class, ourCtx.newJsonParser().parseResource(" {\"resourceType\" : \"Bundle\"}").getClass());
|
||||||
|
|
|
@ -1999,37 +1999,23 @@ public class XmlParserDstu2_1Test {
|
||||||
" \"resourceType\": \"Patient\",",
|
" \"resourceType\": \"Patient\",",
|
||||||
" \"id\": \"someid\",",
|
" \"id\": \"someid\",",
|
||||||
" \"_id\": {",
|
" \"_id\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 1 \" ]",
|
||||||
" \" comment 1 \"",
|
|
||||||
" ]",
|
|
||||||
" },",
|
" },",
|
||||||
" \"extension\": [",
|
" \"extension\": [ {",
|
||||||
" {",
|
" \"fhir_comments\": [ \" comment 2 \", \" comment 7 \" ],",
|
||||||
" \"fhir_comments\": [",
|
|
||||||
" \" comment 2 \",",
|
|
||||||
" \" comment 7 \"",
|
|
||||||
" ],",
|
|
||||||
" \"url\": \"urn:patientext:att\",",
|
" \"url\": \"urn:patientext:att\",",
|
||||||
" \"valueAttachment\": {",
|
" \"valueAttachment\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 3 \", \" comment 6 \" ],",
|
||||||
" \" comment 3 \",",
|
|
||||||
" \" comment 6 \"",
|
|
||||||
" ],",
|
|
||||||
" \"contentType\": \"aaaa\",",
|
" \"contentType\": \"aaaa\",",
|
||||||
" \"_contentType\": {",
|
" \"_contentType\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 4 \" ]",
|
||||||
" \" comment 4 \"",
|
|
||||||
" ]",
|
|
||||||
" },",
|
" },",
|
||||||
" \"data\": \"AAAA\",",
|
" \"data\": \"AAAA\",",
|
||||||
" \"_data\": {",
|
" \"_data\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 5 \" ]",
|
||||||
" \" comment 5 \"",
|
|
||||||
" ]",
|
|
||||||
" }",
|
" }",
|
||||||
" }",
|
" }",
|
||||||
" }",
|
" } ]",
|
||||||
" ]",
|
|
||||||
"}"
|
"}"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -498,37 +498,28 @@ public class JsonParserDstu2Test {
|
||||||
String enc = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
|
String enc = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
|
||||||
ourLog.info(enc);
|
ourLog.info(enc);
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
String actual = enc.trim();
|
String actual = enc.trim();
|
||||||
ourLog.info("Actual:\n{}", actual);
|
ourLog.info("Actual:\n{}", actual);
|
||||||
|
|
||||||
assertEquals("{\n" +
|
assertThat(actual, stringContainsInOrder("{",
|
||||||
" \"resourceType\": \"Patient\",\n" +
|
" \"resourceType\": \"Patient\",",
|
||||||
" \"meta\": {\n" +
|
" \"meta\": {",
|
||||||
" \"security\": [\n" +
|
" \"security\": [ {",
|
||||||
" {\n" +
|
" \"system\": \"SYSTEM1\",",
|
||||||
" \"system\": \"SYSTEM1\",\n" +
|
" \"version\": \"VERSION1\",",
|
||||||
" \"version\": \"VERSION1\",\n" +
|
" \"code\": \"CODE1\",",
|
||||||
" \"code\": \"CODE1\",\n" +
|
" \"display\": \"DISPLAY1\"",
|
||||||
" \"display\": \"DISPLAY1\"\n" +
|
" }, {",
|
||||||
" },\n" +
|
" \"system\": \"SYSTEM2\",",
|
||||||
" {\n" +
|
" \"version\": \"VERSION2\",",
|
||||||
" \"system\": \"SYSTEM2\",\n" +
|
" \"code\": \"CODE2\",",
|
||||||
" \"version\": \"VERSION2\",\n" +
|
" \"display\": \"DISPLAY2\"",
|
||||||
" \"code\": \"CODE2\",\n" +
|
" } ]",
|
||||||
" \"display\": \"DISPLAY2\"\n" +
|
" },",
|
||||||
" }\n" +
|
" \"name\": [ {",
|
||||||
" ]\n" +
|
" \"family\": [ \"FAMILY\" ]",
|
||||||
" },\n" +
|
" } ]",
|
||||||
" \"name\": [\n" +
|
"}"));
|
||||||
" {\n" +
|
|
||||||
" \"family\": [\n" +
|
|
||||||
" \"FAMILY\"\n" +
|
|
||||||
" ]\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ]\n" +
|
|
||||||
"}", actual);
|
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, enc);
|
Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, enc);
|
||||||
List<BaseCodingDt> gotLabels = ResourceMetadataKeyEnum.SECURITY_LABELS.get(parsed);
|
List<BaseCodingDt> gotLabels = ResourceMetadataKeyEnum.SECURITY_LABELS.get(parsed);
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
package ca.uhn.fhir.parser.jsonlike;
|
package ca.uhn.fhir.parser.jsonlike;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.parser.IJsonLikeParser;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
||||||
|
import ca.uhn.fhir.parser.json.jackson.JacksonStructure;
|
||||||
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import java.io.StringReader;
|
||||||
import ca.uhn.fhir.parser.IJsonLikeParser;
|
|
||||||
import ca.uhn.fhir.parser.json.GsonStructure;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
|
||||||
|
|
||||||
public class JsonLikeParserDstu2Test {
|
public class JsonLikeParserDstu2Test {
|
||||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||||
|
@ -28,7 +27,7 @@ public class JsonLikeParserDstu2Test {
|
||||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
|
||||||
ourLog.info(encoded);
|
ourLog.info(encoded);
|
||||||
|
|
||||||
JsonLikeStructure jsonLikeStructure = new GsonStructure();
|
JsonLikeStructure jsonLikeStructure = new JacksonStructure();
|
||||||
jsonLikeStructure.load(new StringReader(encoded));
|
jsonLikeStructure.load(new StringReader(encoded));
|
||||||
|
|
||||||
IJsonLikeParser jsonLikeparser = (IJsonLikeParser)ourCtx.newJsonParser();
|
IJsonLikeParser jsonLikeparser = (IJsonLikeParser)ourCtx.newJsonParser();
|
||||||
|
|
|
@ -72,7 +72,8 @@ public class JsonParserDstu3Test {
|
||||||
p.parseResource(input);
|
p.parseResource(input);
|
||||||
fail();
|
fail();
|
||||||
} catch (DataFormatException e) {
|
} catch (DataFormatException e) {
|
||||||
assertEquals("Found incorrect type for element subject - Expected OBJECT and found SCALAR (STRING)", e.getMessage());
|
assertEquals("Failed to parse JSON encoded FHIR content: Unexpected character ('=' (code 61)): was expecting a colon to separate field name and value\n" +
|
||||||
|
" at [Source: UNKNOWN; line: 4, column: 18]", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,32 +489,25 @@ public class JsonParserDstu3Test {
|
||||||
String enc = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
|
String enc = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
|
||||||
ourLog.info(enc);
|
ourLog.info(enc);
|
||||||
|
|
||||||
//@formatter:off
|
assertThat(enc.trim(), stringContainsInOrder("{",
|
||||||
assertEquals("{\n" +
|
" \"resourceType\": \"Patient\",",
|
||||||
" \"resourceType\": \"Patient\",\n" +
|
" \"meta\": {",
|
||||||
" \"meta\": {\n" +
|
" \"security\": [ {",
|
||||||
" \"security\": [\n" +
|
" \"system\": \"SYSTEM1\",",
|
||||||
" {\n" +
|
" \"version\": \"VERSION1\",",
|
||||||
" \"system\": \"SYSTEM1\",\n" +
|
" \"code\": \"CODE1\",",
|
||||||
" \"version\": \"VERSION1\",\n" +
|
" \"display\": \"DISPLAY1\"",
|
||||||
" \"code\": \"CODE1\",\n" +
|
" }, {",
|
||||||
" \"display\": \"DISPLAY1\"\n" +
|
" \"system\": \"SYSTEM2\",",
|
||||||
" },\n" +
|
" \"version\": \"VERSION2\",",
|
||||||
" {\n" +
|
" \"code\": \"CODE2\",",
|
||||||
" \"system\": \"SYSTEM2\",\n" +
|
" \"display\": \"DISPLAY2\"",
|
||||||
" \"version\": \"VERSION2\",\n" +
|
" } ]",
|
||||||
" \"code\": \"CODE2\",\n" +
|
" },",
|
||||||
" \"display\": \"DISPLAY2\"\n" +
|
" \"name\": [ {",
|
||||||
" }\n" +
|
" \"family\": \"FAMILY\"",
|
||||||
" ]\n" +
|
" } ]",
|
||||||
" },\n" +
|
"}"));
|
||||||
" \"name\": [\n" +
|
|
||||||
" {\n" +
|
|
||||||
" \"family\": \"FAMILY\"\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ]\n" +
|
|
||||||
"}", enc.trim());
|
|
||||||
//@formatter:on
|
|
||||||
|
|
||||||
Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, enc);
|
Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, enc);
|
||||||
List<Coding> gotLabels = parsed.getMeta().getSecurity();
|
List<Coding> gotLabels = parsed.getMeta().getSecurity();
|
||||||
|
@ -1401,7 +1395,8 @@ public class JsonParserDstu3Test {
|
||||||
String input = "{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.0000000000000001}}";
|
String input = "{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.0000000000000001}}";
|
||||||
Observation obs = ourCtx.newJsonParser().parseResource(Observation.class, input);
|
Observation obs = ourCtx.newJsonParser().parseResource(Observation.class, input);
|
||||||
|
|
||||||
assertEquals("0.0000000000000001", ((Quantity) obs.getValue()).getValueElement().getValueAsString());
|
DecimalType valueElement = ((Quantity) obs.getValue()).getValueElement();
|
||||||
|
assertEquals("0.0000000000000001", valueElement.getValueAsString());
|
||||||
|
|
||||||
String str = ourCtx.newJsonParser().encodeResourceToString(obs);
|
String str = ourCtx.newJsonParser().encodeResourceToString(obs);
|
||||||
ourLog.info(str);
|
ourLog.info(str);
|
||||||
|
@ -1993,13 +1988,13 @@ public class JsonParserDstu3Test {
|
||||||
ourCtx.newJsonParser().parseResource("FOO");
|
ourCtx.newJsonParser().parseResource("FOO");
|
||||||
fail();
|
fail();
|
||||||
} catch (DataFormatException e) {
|
} catch (DataFormatException e) {
|
||||||
assertEquals("Failed to parse JSON content, error was: Content does not appear to be FHIR JSON, first non-whitespace character was: 'F' (must be '{')", e.getMessage());
|
assertEquals("Failed to parse JSON encoded FHIR content: Content does not appear to be FHIR JSON, first non-whitespace character was: 'F' (must be '{')", e.getMessage());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ourCtx.newJsonParser().parseResource("[\"aaa\"]");
|
ourCtx.newJsonParser().parseResource("[\"aaa\"]");
|
||||||
fail();
|
fail();
|
||||||
} catch (DataFormatException e) {
|
} catch (DataFormatException e) {
|
||||||
assertEquals("Failed to parse JSON content, error was: Content does not appear to be FHIR JSON, first non-whitespace character was: '[' (must be '{')", e.getMessage());
|
assertEquals("Failed to parse JSON encoded FHIR content: Content does not appear to be FHIR JSON, first non-whitespace character was: '[' (must be '{')", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(Bundle.class, ourCtx.newJsonParser().parseResource(" {\"resourceType\" : \"Bundle\"}").getClass());
|
assertEquals(Bundle.class, ourCtx.newJsonParser().parseResource(" {\"resourceType\" : \"Bundle\"}").getClass());
|
||||||
|
@ -2221,25 +2216,47 @@ public class JsonParserDstu3Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseWithPrecision() {
|
public void testParseWithPrecision() {
|
||||||
|
|
||||||
|
// BigDecimal d0 = new BigDecimal("0.1");
|
||||||
|
// BigDecimal d1 = new BigDecimal("0.1000");
|
||||||
|
//
|
||||||
|
// ourLog.info("Value: {}", d0);
|
||||||
|
// ourLog.info("Value: {}", d1);
|
||||||
|
|
||||||
|
{
|
||||||
|
String input = "{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.0100}}";
|
||||||
|
Observation obs = ourCtx.newJsonParser().parseResource(Observation.class, input);
|
||||||
|
DecimalType valueElement = ((Quantity) obs.getValue()).getValueElement();
|
||||||
|
assertEquals("0.0100", valueElement.getValueAsString());
|
||||||
|
String str = ourCtx.newJsonParser().encodeResourceToString(obs);
|
||||||
|
ourLog.info(str);
|
||||||
|
assertEquals("{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.0100}}", str);
|
||||||
|
}
|
||||||
|
{
|
||||||
String input = "{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.000000000000000100}}";
|
String input = "{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.000000000000000100}}";
|
||||||
Observation obs = ourCtx.newJsonParser().parseResource(Observation.class, input);
|
Observation obs = ourCtx.newJsonParser().parseResource(Observation.class, input);
|
||||||
|
|
||||||
DecimalType valueElement = ((Quantity) obs.getValue()).getValueElement();
|
DecimalType valueElement = ((Quantity) obs.getValue()).getValueElement();
|
||||||
assertEquals("0.000000000000000100", valueElement.getValueAsString());
|
assertEquals("0.000000000000000100", valueElement.getValueAsString());
|
||||||
|
|
||||||
String str = ourCtx.newJsonParser().encodeResourceToString(obs);
|
String str = ourCtx.newJsonParser().encodeResourceToString(obs);
|
||||||
ourLog.info(str);
|
ourLog.info(str);
|
||||||
assertEquals("{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.000000000000000100}}", str);
|
assertEquals("{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.000000000000000100}}", str);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = DataFormatException.class)
|
@Test
|
||||||
public void testParseWithTrailingContent() {
|
public void testParseWithTrailingContent() {
|
||||||
String bundle = "{\n" +
|
String bundle = "{\n" +
|
||||||
" \"resourceType\": \"Bundle\",\n" +
|
" \"resourceType\": \"Bundle\",\n" +
|
||||||
" \"total\": 1\n" +
|
" \"total\": 1\n" +
|
||||||
"}}";
|
"}}";
|
||||||
|
|
||||||
|
try {
|
||||||
ourCtx.newJsonParser().parseResource(Bundle.class, bundle);
|
ourCtx.newJsonParser().parseResource(Bundle.class, bundle);
|
||||||
|
fail();
|
||||||
|
} catch (DataFormatException e) {
|
||||||
|
assertEquals("Failed to parse JSON encoded FHIR content: Unexpected close marker '}': expected ']' (for root starting at [Source: UNKNOWN; line: 1, column: 0])\n" +
|
||||||
|
" at [Source: UNKNOWN; line: 4, column: 3]", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -2508,42 +2508,27 @@ public class XmlParserDstu3Test {
|
||||||
output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat);
|
output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
|
|
||||||
assertThat(output, stringContainsInOrder(
|
assertThat(output, stringContainsInOrder("{",
|
||||||
"{",
|
|
||||||
" \"resourceType\": \"Patient\",",
|
" \"resourceType\": \"Patient\",",
|
||||||
" \"id\": \"someid\",",
|
" \"id\": \"someid\",",
|
||||||
" \"_id\": {",
|
" \"_id\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 1 \" ]",
|
||||||
" \" comment 1 \"",
|
|
||||||
" ]",
|
|
||||||
" },",
|
" },",
|
||||||
" \"extension\": [",
|
" \"extension\": [ {",
|
||||||
" {",
|
" \"fhir_comments\": [ \" comment 2 \", \" comment 7 \" ],",
|
||||||
" \"fhir_comments\": [",
|
|
||||||
" \" comment 2 \",",
|
|
||||||
" \" comment 7 \"",
|
|
||||||
" ],",
|
|
||||||
" \"url\": \"urn:patientext:att\",",
|
" \"url\": \"urn:patientext:att\",",
|
||||||
" \"valueAttachment\": {",
|
" \"valueAttachment\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 3 \", \" comment 6 \" ],",
|
||||||
" \" comment 3 \",",
|
|
||||||
" \" comment 6 \"",
|
|
||||||
" ],",
|
|
||||||
" \"contentType\": \"aaaa\",",
|
" \"contentType\": \"aaaa\",",
|
||||||
" \"_contentType\": {",
|
" \"_contentType\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 4 \" ]",
|
||||||
" \" comment 4 \"",
|
|
||||||
" ]",
|
|
||||||
" },",
|
" },",
|
||||||
" \"data\": \"AAAA\",",
|
" \"data\": \"AAAA\",",
|
||||||
" \"_data\": {",
|
" \"_data\": {",
|
||||||
" \"fhir_comments\": [",
|
" \"fhir_comments\": [ \" comment 5 \" ]",
|
||||||
" \" comment 5 \"",
|
|
||||||
" ]",
|
|
||||||
" }",
|
" }",
|
||||||
" }",
|
" }",
|
||||||
" }",
|
" } ]",
|
||||||
" ]",
|
|
||||||
"}"));
|
"}"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
package ca.uhn.fhir.parser.jsonlike;
|
package ca.uhn.fhir.parser.jsonlike;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.parser.IJsonLikeParser;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeWriter;
|
||||||
|
import ca.uhn.fhir.parser.json.jackson.JacksonStructure;
|
||||||
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle;
|
||||||
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
|
import org.hl7.fhir.dstu3.model.Reference;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
@ -10,22 +24,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.hl7.fhir.dstu3.model.Bundle;
|
|
||||||
import org.hl7.fhir.dstu3.model.Extension;
|
|
||||||
import org.hl7.fhir.dstu3.model.Patient;
|
|
||||||
import org.hl7.fhir.dstu3.model.Reference;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.parser.IJsonLikeParser;
|
|
||||||
import ca.uhn.fhir.parser.json.GsonStructure;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeWriter;
|
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
|
||||||
|
|
||||||
public class JsonLikeParserDstu3Test {
|
public class JsonLikeParserDstu3Test {
|
||||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonLikeParserDstu3Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonLikeParserDstu3Test.class);
|
||||||
|
@ -42,7 +40,7 @@ public class JsonLikeParserDstu3Test {
|
||||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
|
||||||
ourLog.info(encoded);
|
ourLog.info(encoded);
|
||||||
|
|
||||||
JsonLikeStructure jsonLikeStructure = new GsonStructure();
|
JsonLikeStructure jsonLikeStructure = new JacksonStructure();
|
||||||
jsonLikeStructure.load(new StringReader(encoded));
|
jsonLikeStructure.load(new StringReader(encoded));
|
||||||
|
|
||||||
IJsonLikeParser jsonLikeparser = (IJsonLikeParser)ourCtx.newJsonParser();
|
IJsonLikeParser jsonLikeparser = (IJsonLikeParser)ourCtx.newJsonParser();
|
||||||
|
@ -192,17 +190,6 @@ public class JsonLikeParserDstu3Test {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter beginArray() throws IOException {
|
|
||||||
if (currentBlock.getType() == BlockType.NONE) {
|
|
||||||
throw new IOException("JsonLikeStreamWriter.beginArray() called but only beginObject() is allowed here.");
|
|
||||||
}
|
|
||||||
blockStack.push(currentBlock);
|
|
||||||
currentBlock = new Block(BlockType.ARRAY);
|
|
||||||
currentBlock.setArray(new ArrayList<Object>());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeWriter beginObject(String name) throws IOException {
|
public JsonLikeWriter beginObject(String name) throws IOException {
|
||||||
if (currentBlock.getType() == BlockType.ARRAY) {
|
if (currentBlock.getType() == BlockType.ARRAY) {
|
||||||
|
@ -363,15 +350,6 @@ public class JsonLikeParserDstu3Test {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter writeNull(String name) throws IOException {
|
|
||||||
if (currentBlock.getType() == BlockType.ARRAY) {
|
|
||||||
throw new IOException("Named JSON elements can only be created in JSON objects");
|
|
||||||
}
|
|
||||||
currentBlock.getObject().put(name, null);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeWriter endObject() throws IOException {
|
public JsonLikeWriter endObject() throws IOException {
|
||||||
if (currentBlock.getType() == BlockType.NONE) {
|
if (currentBlock.getType() == BlockType.NONE) {
|
||||||
|
@ -399,7 +377,7 @@ public class JsonLikeParserDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeWriter endBlock() throws IOException {
|
public JsonLikeWriter endBlock() {
|
||||||
if (currentBlock.getType() == BlockType.NONE) {
|
if (currentBlock.getType() == BlockType.NONE) {
|
||||||
ourLog.error("JsonLikeStreamWriter.endBlock(); called with no active JSON document");
|
ourLog.error("JsonLikeStreamWriter.endBlock(); called with no active JSON document");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1097,12 +1097,6 @@ public class JsonParserHl7OrgDstu2Test {
|
||||||
assertEquals("idsystem", p.getIdentifier().get(0).getSystem());
|
assertEquals("idsystem", p.getIdentifier().get(0).getSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParseSingleQuotes() {
|
|
||||||
ourCtx.newJsonParser().parseResource(Bundle.class, "{ \"resourceType\": \"Bundle\" }");
|
|
||||||
ourCtx.newJsonParser().parseResource(Bundle.class, "{ 'resourceType': 'Bundle' }");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HAPI FHIR < 0.6 incorrectly used "resource" instead of "reference"
|
* HAPI FHIR < 0.6 incorrectly used "resource" instead of "reference"
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -175,6 +175,11 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.awaitility</groupId>
|
||||||
|
<artifactId>awaitility</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Dependencies for Schematron -->
|
<!-- Dependencies for Schematron -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -215,9 +220,8 @@
|
||||||
|
|
||||||
<!-- UNIT TEST DEPENDENCIES -->
|
<!-- UNIT TEST DEPENDENCIES -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.jena</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>apache-jena-libs</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<type>pom</type>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -248,6 +248,12 @@ public class JsonParserR4Test extends BaseTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseSingleQuotes() {
|
||||||
|
Bundle bundle = ourCtx.newJsonParser().parseResource(Bundle.class, "{ 'resourceType': 'Bundle', 'id': '123' }");
|
||||||
|
assertEquals("123", bundle.getIdElement().getIdPart());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeBinary() {
|
public void testEncodeBinary() {
|
||||||
|
@ -260,6 +266,18 @@ public class JsonParserR4Test extends BaseTest {
|
||||||
assertEquals("{\"resourceType\":\"Binary\",\"contentType\":\"application/octet-stream\",\"data\":\"AAECAwQ=\"}", output);
|
assertEquals("{\"resourceType\":\"Binary\",\"contentType\":\"application/octet-stream\",\"data\":\"AAECAwQ=\"}", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAlwaysUseUnixNewlines() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.setId("1");
|
||||||
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
|
||||||
|
assertEquals("{\n" +
|
||||||
|
" \"resourceType\": \"Patient\",\n" +
|
||||||
|
" \"id\": \"1\"\n" +
|
||||||
|
"}", encoded);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeWithInvalidExtensionMissingUrl() {
|
public void testEncodeWithInvalidExtensionMissingUrl() {
|
||||||
|
|
||||||
|
@ -586,6 +604,14 @@ public class JsonParserR4Test extends BaseTest {
|
||||||
* 15:20:41.708 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:574] - Encoded 1200 passes - 28ms / pass - 34.5 / second
|
* 15:20:41.708 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:574] - Encoded 1200 passes - 28ms / pass - 34.5 / second
|
||||||
* 15:20:44.722 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:574] - Encoded 1300 passes - 29ms / pass - 34.4 / second
|
* 15:20:44.722 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:574] - Encoded 1300 passes - 29ms / pass - 34.4 / second
|
||||||
* 15:20:47.716 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:574] - Encoded 1400 passes - 29ms / pass - 34.4 / second
|
* 15:20:47.716 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:574] - Encoded 1400 passes - 29ms / pass - 34.4 / second
|
||||||
|
*
|
||||||
|
* 2020-02-27 - Post #1673
|
||||||
|
* 21:27:25.817 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:609] - Encoded 1100 passes - 28ms / pass - 35.5 / second
|
||||||
|
* 21:27:28.598 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:609] - Encoded 1200 passes - 28ms / pass - 35.5 / second
|
||||||
|
* 21:27:31.436 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:609] - Encoded 1300 passes - 28ms / pass - 35.5 / second
|
||||||
|
* 21:27:34.246 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:609] - Encoded 1400 passes - 28ms / pass - 35.5 / second
|
||||||
|
* 21:27:37.013 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:609] - Encoded 1500 passes - 28ms / pass - 35.6 / second
|
||||||
|
* 21:27:39.874 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:609] - Encoded 1600 passes - 28ms / pass - 35.5 / second
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
|
@ -655,6 +681,12 @@ public class JsonParserR4Test extends BaseTest {
|
||||||
* 15:22:40.699 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:638] - Parsed 2500 passes - 12ms / pass - 79.7 / second
|
* 15:22:40.699 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:638] - Parsed 2500 passes - 12ms / pass - 79.7 / second
|
||||||
* 15:22:42.135 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:638] - Parsed 2600 passes - 12ms / pass - 79.3 / second
|
* 15:22:42.135 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:638] - Parsed 2600 passes - 12ms / pass - 79.3 / second
|
||||||
*
|
*
|
||||||
|
* 2020-02-27 - Post #1673
|
||||||
|
* 21:29:38.157 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:687] - Parsed 2200 passes - 11ms / pass - 83.4 / second
|
||||||
|
* 21:29:39.374 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:687] - Parsed 2300 passes - 12ms / pass - 83.3 / second
|
||||||
|
* 21:29:40.576 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:687] - Parsed 2400 passes - 12ms / pass - 83.3 / second
|
||||||
|
* 21:29:41.778 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:687] - Parsed 2500 passes - 12ms / pass - 83.3 / second
|
||||||
|
* 21:29:42.999 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:687] - Parsed 2600 passes - 12ms / pass - 83.3 / second
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,5 +1,26 @@
|
||||||
package ca.uhn.fhir.parser.jsonlike;
|
package ca.uhn.fhir.parser.jsonlike;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
import ca.uhn.fhir.parser.IJsonLikeParser;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeArray;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeObject;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeValue;
|
||||||
|
import ca.uhn.fhir.parser.json.JsonLikeWriter;
|
||||||
|
import ca.uhn.fhir.parser.json.jackson.JacksonStructure;
|
||||||
|
import ca.uhn.fhir.parser.view.ExtPatient;
|
||||||
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.r4.model.Extension;
|
||||||
|
import org.hl7.fhir.r4.model.IntegerType;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
@ -14,31 +35,6 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
import org.hl7.fhir.r4.model.IntegerType;
|
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
|
||||||
import org.hl7.fhir.r4.model.Extension;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
|
||||||
import ca.uhn.fhir.parser.IJsonLikeParser;
|
|
||||||
import ca.uhn.fhir.parser.IParser;
|
|
||||||
import ca.uhn.fhir.parser.json.GsonStructure;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeArray;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeObject;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeStructure;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeWriter;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
|
|
||||||
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
|
|
||||||
import ca.uhn.fhir.parser.view.ExtPatient;
|
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
|
||||||
|
|
||||||
public class JsonLikeParserTest {
|
public class JsonLikeParserTest {
|
||||||
private static FhirContext ourCtx = FhirContext.forR4();
|
private static FhirContext ourCtx = FhirContext.forR4();
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonLikeParserTest.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonLikeParserTest.class);
|
||||||
|
@ -55,7 +51,7 @@ public class JsonLikeParserTest {
|
||||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
|
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
|
||||||
ourLog.info(encoded);
|
ourLog.info(encoded);
|
||||||
|
|
||||||
JsonLikeStructure jsonLikeStructure = new GsonStructure();
|
JsonLikeStructure jsonLikeStructure = new JacksonStructure();
|
||||||
jsonLikeStructure.load(new StringReader(encoded));
|
jsonLikeStructure.load(new StringReader(encoded));
|
||||||
|
|
||||||
IJsonLikeParser jsonLikeparser = (IJsonLikeParser)ourCtx.newJsonParser();
|
IJsonLikeParser jsonLikeparser = (IJsonLikeParser)ourCtx.newJsonParser();
|
||||||
|
@ -258,17 +254,6 @@ public class JsonLikeParserTest {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter beginArray() throws IOException {
|
|
||||||
if (currentBlock.getType() == BlockType.NONE) {
|
|
||||||
throw new IOException("JsonLikeStreamWriter.beginArray() called but only beginObject() is allowed here.");
|
|
||||||
}
|
|
||||||
blockStack.push(currentBlock);
|
|
||||||
currentBlock = new Block(BlockType.ARRAY);
|
|
||||||
currentBlock.setArray(new ArrayList<Object>());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeWriter beginObject(String name) throws IOException {
|
public JsonLikeWriter beginObject(String name) throws IOException {
|
||||||
if (currentBlock.getType() == BlockType.ARRAY) {
|
if (currentBlock.getType() == BlockType.ARRAY) {
|
||||||
|
@ -429,15 +414,6 @@ public class JsonLikeParserTest {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeWriter writeNull(String name) throws IOException {
|
|
||||||
if (currentBlock.getType() == BlockType.ARRAY) {
|
|
||||||
throw new IOException("Named JSON elements can only be created in JSON objects");
|
|
||||||
}
|
|
||||||
currentBlock.getObject().put(name, null);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeWriter endObject() throws IOException {
|
public JsonLikeWriter endObject() throws IOException {
|
||||||
if (currentBlock.getType() == BlockType.NONE) {
|
if (currentBlock.getType() == BlockType.NONE) {
|
||||||
|
@ -452,7 +428,7 @@ public class JsonLikeParserTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeWriter endArray() throws IOException {
|
public JsonLikeWriter endArray() {
|
||||||
if (currentBlock.getType() == BlockType.NONE) {
|
if (currentBlock.getType() == BlockType.NONE) {
|
||||||
ourLog.error("JsonLikeStreamWriter.endArray(); called with no active JSON document");
|
ourLog.error("JsonLikeStreamWriter.endArray(); called with no active JSON document");
|
||||||
} else {
|
} else {
|
||||||
|
@ -465,11 +441,11 @@ public class JsonLikeParserTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeWriter endBlock() throws IOException {
|
public JsonLikeWriter endBlock() {
|
||||||
if (currentBlock.getType() == BlockType.NONE) {
|
if (currentBlock.getType() == BlockType.NONE) {
|
||||||
ourLog.error("JsonLikeStreamWriter.endBlock(); called with no active JSON document");
|
ourLog.error("JsonLikeStreamWriter.endBlock(); called with no active JSON document");
|
||||||
} else {
|
} else {
|
||||||
Object toPut = null;
|
Object toPut;
|
||||||
if (currentBlock.getType() == BlockType.ARRAY) {
|
if (currentBlock.getType() == BlockType.ARRAY) {
|
||||||
toPut = currentBlock.getArray();
|
toPut = currentBlock.getArray();
|
||||||
} else {
|
} else {
|
||||||
|
@ -544,14 +520,9 @@ public class JsonLikeParserTest {
|
||||||
return jsonLikeObject;
|
return jsonLikeObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonLikeArray getRootArray() throws DataFormatException {
|
|
||||||
throw new DataFormatException("JSON document must be an object not an array for native Java Map structures");
|
|
||||||
}
|
|
||||||
|
|
||||||
private class JsonMapObject extends JsonLikeObject {
|
private class JsonMapObject extends JsonLikeObject {
|
||||||
private Map<String,Object> nativeObject;
|
private Map<String,Object> nativeObject;
|
||||||
private Map<String,JsonLikeValue> jsonLikeMap = new LinkedHashMap<String,JsonLikeValue>();
|
private Map<String,JsonLikeValue> jsonLikeMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
public JsonMapObject (Map<String,Object> json) {
|
public JsonMapObject (Map<String,Object> json) {
|
||||||
this.nativeObject = json;
|
this.nativeObject = json;
|
||||||
|
@ -585,7 +556,7 @@ public class JsonLikeParserTest {
|
||||||
|
|
||||||
private class JsonMapArray extends JsonLikeArray {
|
private class JsonMapArray extends JsonLikeArray {
|
||||||
private List<Object> nativeArray;
|
private List<Object> nativeArray;
|
||||||
private Map<Integer,JsonLikeValue> jsonLikeMap = new LinkedHashMap<Integer,JsonLikeValue>();
|
private Map<Integer,JsonLikeValue> jsonLikeMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
public JsonMapArray (List<Object> json) {
|
public JsonMapArray (List<Object> json) {
|
||||||
this.nativeArray = json;
|
this.nativeArray = json;
|
||||||
|
@ -603,7 +574,7 @@ public class JsonLikeParserTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonLikeValue get(int index) {
|
public JsonLikeValue get(int index) {
|
||||||
Integer key = Integer.valueOf(index);
|
Integer key = index;
|
||||||
JsonLikeValue result = null;
|
JsonLikeValue result = null;
|
||||||
if (jsonLikeMap.containsKey(key)) {
|
if (jsonLikeMap.containsKey(key)) {
|
||||||
result = jsonLikeMap.get(key);
|
result = jsonLikeMap.get(key);
|
||||||
|
@ -694,7 +665,7 @@ public class JsonLikeParserTest {
|
||||||
@Override
|
@Override
|
||||||
public boolean getAsBoolean() {
|
public boolean getAsBoolean() {
|
||||||
if (nativeValue != null && isBoolean()) {
|
if (nativeValue != null && isBoolean()) {
|
||||||
return ((Boolean)nativeValue).booleanValue();
|
return (Boolean) nativeValue;
|
||||||
}
|
}
|
||||||
return super.getAsBoolean();
|
return super.getAsBoolean();
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ public class BlockingContentR4Test {
|
||||||
if (myByteCount++ == 10) {
|
if (myByteCount++ == 10) {
|
||||||
ourLog.info("About to block...");
|
ourLog.info("About to block...");
|
||||||
try {
|
try {
|
||||||
Thread.sleep(30000);
|
Thread.sleep(3000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
ourLog.warn("Interrupted", e);
|
ourLog.warn("Interrupted", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,12 +35,16 @@ import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.invocation.Invocation;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
@ -201,12 +205,13 @@ public class ConsentInterceptorTest {
|
||||||
assertThat(responseContent, containsString("A DIAG"));
|
assertThat(responseContent, containsString("A DIAG"));
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(myConsentSvc, times(1)).startOperation(any(), any());
|
verify(myConsentSvc, timeout(10000).times(1)).startOperation(any(), any());
|
||||||
verify(myConsentSvc, times(2)).canSeeResource(any(), any(), any());
|
verify(myConsentSvc, timeout(10000).times(2)).canSeeResource(any(), any(), any());
|
||||||
verify(myConsentSvc, times(3)).willSeeResource(any(), any(), any());
|
verify(myConsentSvc, timeout(10000).times(3)).willSeeResource(any(), any(), any());
|
||||||
verify(myConsentSvc, times(1)).completeOperationSuccess(any(), any());
|
verify(myConsentSvc, timeout(10000).times(1)).completeOperationSuccess(any(), any());
|
||||||
verify(myConsentSvc, times(0)).completeOperationFailure(any(), any(), any());
|
verify(myConsentSvc, timeout(10000).times(0)).completeOperationFailure(any(), any(), any());
|
||||||
verifyNoMoreInteractions(myConsentSvc);
|
verifyNoMoreInteractions(myConsentSvc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -241,6 +246,7 @@ public class ConsentInterceptorTest {
|
||||||
ourPatientProvider.store((Patient) new Patient().setActive(true).setId("PTA"));
|
ourPatientProvider.store((Patient) new Patient().setActive(true).setId("PTA"));
|
||||||
ourPatientProvider.store((Patient) new Patient().setActive(false).setId("PTB"));
|
ourPatientProvider.store((Patient) new Patient().setActive(false).setId("PTB"));
|
||||||
|
|
||||||
|
reset(myConsentSvc);
|
||||||
when(myConsentSvc.startOperation(any(), any())).thenReturn(ConsentOutcome.PROCEED);
|
when(myConsentSvc.startOperation(any(), any())).thenReturn(ConsentOutcome.PROCEED);
|
||||||
when(myConsentSvc.canSeeResource(any(), any(), any())).thenReturn(ConsentOutcome.PROCEED);
|
when(myConsentSvc.canSeeResource(any(), any(), any())).thenReturn(ConsentOutcome.PROCEED);
|
||||||
when(myConsentSvc.willSeeResource(any(RequestDetails.class), any(IBaseResource.class), any())).thenAnswer(t->{
|
when(myConsentSvc.willSeeResource(any(RequestDetails.class), any(IBaseResource.class), any())).thenAnswer(t->{
|
||||||
|
@ -266,10 +272,10 @@ public class ConsentInterceptorTest {
|
||||||
assertEquals("PTB", response.getEntry().get(1).getResource().getIdElement().getIdPart());
|
assertEquals("PTB", response.getEntry().get(1).getResource().getIdElement().getIdPart());
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(myConsentSvc, times(1)).startOperation(any(), any());
|
verify(myConsentSvc, timeout(1000).times(1)).startOperation(any(), any());
|
||||||
verify(myConsentSvc, times(2)).canSeeResource(any(), any(), any());
|
verify(myConsentSvc, timeout(1000).times(2)).canSeeResource(any(), any(), any());
|
||||||
verify(myConsentSvc, times(3)).willSeeResource(any(), any(), any());
|
verify(myConsentSvc, timeout(1000).times(3)).willSeeResource(any(), any(), any());
|
||||||
verify(myConsentSvc, times(1)).completeOperationSuccess(any(), any());
|
verify(myConsentSvc, timeout(1000).times(1)).completeOperationSuccess(any(), any());
|
||||||
verify(myConsentSvc, times(0)).completeOperationFailure(any(), any(), any());
|
verify(myConsentSvc, times(0)).completeOperationFailure(any(), any(), any());
|
||||||
verifyNoMoreInteractions(myConsentSvc);
|
verifyNoMoreInteractions(myConsentSvc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import ca.uhn.fhir.rest.annotation.Read;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
|
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
|
@ -21,7 +22,11 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
import org.hl7.fhir.r4.model.Resource;
|
import org.hl7.fhir.r4.model.Resource;
|
||||||
import org.junit.*;
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -30,11 +35,12 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class InterceptorThrowingExceptionR4Test {
|
public class InterceptorThrowingExceptionR4Test {
|
||||||
|
|
||||||
|
@ -84,26 +90,26 @@ public class InterceptorThrowingExceptionR4Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailureInProcessingCompletedNormally() throws Exception {
|
public void testFailureInProcessingCompletedNormally() throws Exception {
|
||||||
final List<Integer> hit = new ArrayList<>();
|
final List<Integer> hit = Collections.synchronizedList(new ArrayList<>());
|
||||||
ourServlet.getInterceptorService().registerInterceptor(new InterceptorAdapter() {
|
ourServlet.getInterceptorService().registerInterceptor(new InterceptorAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void processingCompletedNormally(ServletRequestDetails theRequestDetails) {
|
public void processingCompletedNormally(ServletRequestDetails theRequestDetails) {
|
||||||
hit.add(1);
|
hit.add(1);
|
||||||
throw new NullPointerException();
|
throw new NullPointerException("Hit 1");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ourServlet.getInterceptorService().registerInterceptor(new InterceptorAdapter() {
|
ourServlet.getInterceptorService().registerInterceptor(new InterceptorAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void processingCompletedNormally(ServletRequestDetails theRequestDetails) {
|
public void processingCompletedNormally(ServletRequestDetails theRequestDetails) {
|
||||||
hit.add(2);
|
hit.add(2);
|
||||||
throw new NullPointerException();
|
throw new NullPointerException("Hit 2");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ourServlet.getInterceptorService().registerInterceptor(new InterceptorAdapter() {
|
ourServlet.getInterceptorService().registerInterceptor(new InterceptorAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void processingCompletedNormally(ServletRequestDetails theRequestDetails) {
|
public void processingCompletedNormally(ServletRequestDetails theRequestDetails) {
|
||||||
hit.add(3);
|
hit.add(3);
|
||||||
throw new NullPointerException();
|
throw new NullPointerException("Hit 3");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -119,6 +125,9 @@ public class InterceptorThrowingExceptionR4Test {
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
assertThat(response, containsString("FAM"));
|
assertThat(response, containsString("FAM"));
|
||||||
assertTrue(ourHitMethod);
|
assertTrue(ourHitMethod);
|
||||||
|
|
||||||
|
await().until(() -> hit.size() == 3);
|
||||||
|
|
||||||
ourLog.info("Hit: {}", hit);
|
ourLog.info("Hit: {}", hit);
|
||||||
assertThat("Hits: " + hit.toString(), hit, contains(1, 2, 3));
|
assertThat("Hits: " + hit.toString(), hit, contains(1, 2, 3));
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,10 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--<dependency> <groupId>ca.uhn.hapi.fhir</groupId> <artifactId>hapi-fhir-structures-dev</artifactId> <version>0.9</version> </dependency> -->
|
<!--<dependency> <groupId>ca.uhn.hapi.fhir</groupId> <artifactId>hapi-fhir-structures-dev</artifactId> <version>0.9</version> </dependency> -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thymeleaf</groupId>
|
<groupId>org.thymeleaf</groupId>
|
||||||
<artifactId>thymeleaf</artifactId>
|
<artifactId>thymeleaf</artifactId>
|
||||||
|
|
|
@ -1,42 +1,59 @@
|
||||||
package ca.uhn.fhir.to;
|
package ca.uhn.fhir.to;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
|
||||||
|
import ca.uhn.fhir.model.primitive.BoundCodeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
|
import ca.uhn.fhir.rest.client.impl.GenericClient;
|
||||||
|
import ca.uhn.fhir.rest.gclient.ICreateTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IHistory;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IHistoryTyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IHistoryUntyped;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IQuery;
|
||||||
|
import ca.uhn.fhir.rest.gclient.IUntypedQuery;
|
||||||
|
import ca.uhn.fhir.rest.gclient.NumberClientParam.IMatches;
|
||||||
|
import ca.uhn.fhir.rest.gclient.QuantityClientParam;
|
||||||
|
import ca.uhn.fhir.rest.gclient.QuantityClientParam.IAndUnits;
|
||||||
|
import ca.uhn.fhir.rest.gclient.StringClientParam;
|
||||||
|
import ca.uhn.fhir.rest.gclient.TokenClientParam;
|
||||||
|
import ca.uhn.fhir.to.model.HomeRequest;
|
||||||
|
import ca.uhn.fhir.to.model.ResourceRequest;
|
||||||
|
import ca.uhn.fhir.to.model.TransactionRequest;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hl7.fhir.dstu3.model.CapabilityStatement;
|
||||||
|
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
|
||||||
|
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
|
||||||
|
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
|
||||||
|
import org.hl7.fhir.dstu3.model.StringType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultIfEmpty;
|
import static org.apache.commons.lang3.StringUtils.defaultIfEmpty;
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.hl7.fhir.dstu3.model.CapabilityStatement;
|
|
||||||
import org.hl7.fhir.dstu3.model.CapabilityStatement.*;
|
|
||||||
import org.hl7.fhir.dstu3.model.StringType;
|
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
|
||||||
import org.springframework.ui.ModelMap;
|
|
||||||
import org.springframework.validation.BindingResult;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.*;
|
|
||||||
import ca.uhn.fhir.model.api.Include;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Conformance;
|
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
|
|
||||||
import ca.uhn.fhir.model.primitive.*;
|
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
|
||||||
import ca.uhn.fhir.rest.client.impl.GenericClient;
|
|
||||||
import ca.uhn.fhir.rest.gclient.*;
|
|
||||||
import ca.uhn.fhir.rest.gclient.NumberClientParam.IMatches;
|
|
||||||
import ca.uhn.fhir.rest.gclient.QuantityClientParam.IAndUnits;
|
|
||||||
import ca.uhn.fhir.to.model.*;
|
|
||||||
|
|
||||||
@org.springframework.stereotype.Controller()
|
@org.springframework.stereotype.Controller()
|
||||||
public class Controller extends BaseController {
|
public class Controller extends BaseController {
|
||||||
static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Controller.class);
|
static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Controller.class);
|
||||||
|
|
|
@ -46,6 +46,15 @@
|
||||||
<artifactId>jsr305</artifactId>
|
<artifactId>jsr305</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Note: As of HAPI FHIR 5.0.0 we now use Jackson for JSON parsing, but the
|
||||||
|
validator still uses GSON so it is a dependency here
|
||||||
|
-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Optional dependencies from RI codebase
|
Optional dependencies from RI codebase
|
||||||
-->
|
-->
|
||||||
|
|
Loading…
Reference in New Issue