All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.ibm.fhir.model.util.JsonSupport Maven / Gradle / Ivy
/*
* (C) Copyright IBM Corp. 2019, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/
package com.ibm.fhir.model.util;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.FilterReader;
import java.io.FilterWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonReaderFactory;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import com.ibm.fhir.model.format.Format;
import com.ibm.fhir.model.generator.FHIRGenerator;
import com.ibm.fhir.model.generator.exception.FHIRGeneratorException;
import com.ibm.fhir.model.resource.Resource;
public final class JsonSupport {
private static final JsonReaderFactory JSON_READER_FACTORY = Json.createReaderFactory(null);
private static final Map, Set> ELEMENT_NAME_MAP = buildElementNameMap(false);
private static final Map, Set> REQUIRED_ELEMENT_NAME_MAP = buildElementNameMap(true);
private static final Map, Set> SUMMARY_ELEMENT_NAME_MAP = buildSummaryElementNameMap();
private static final Map, Set> SUMMARY_DATA_ELEMENT_NAME_MAP = new LinkedHashMap<>();
private JsonSupport() { }
/**
* Calling this method allows us to load/initialize this class during startup.
*/
public static void init() { }
private static Map, Set> buildElementNameMap(boolean required) {
Map, Set> elementNameMap = new LinkedHashMap<>();
for (Class modelClass : ModelSupport.getModelClasses()) {
if (ModelSupport.isPrimitiveType(modelClass)) {
continue;
}
Set elementNames = new LinkedHashSet<>();
for (String elementName : ModelSupport.getElementNames(modelClass)) {
if (required && !ModelSupport.isRequiredElement(modelClass, elementName)) {
continue;
}
if (ModelSupport.isChoiceElement(modelClass, elementName)) {
for (Class choiceElementType : ModelSupport.getChoiceElementTypes(modelClass, elementName)) {
String choiceElementName = ModelSupport.getChoiceElementName(elementName, choiceElementType);
elementNames.add(choiceElementName);
if (ModelSupport.isPrimitiveType(choiceElementType)) {
elementNames.add("_" + choiceElementName);
}
}
} else {
elementNames.add(elementName);
Class elementType = ModelSupport.getElementType(modelClass, elementName);
if (ModelSupport.isPrimitiveType(elementType)) {
elementNames.add("_" + elementName);
}
}
}
elementNameMap.put(modelClass, Collections.unmodifiableSet(elementNames));
}
return Collections.unmodifiableMap(elementNameMap);
}
private static Map, Set> buildSummaryElementNameMap() {
Map, Set> summaryElementNameMap = new LinkedHashMap<>();
for (Class modelClass : ModelSupport.getModelClasses()) {
if (ModelSupport.isPrimitiveType(modelClass)) {
continue;
}
Set elementNames = new LinkedHashSet<>();
for (String elementName : ModelSupport.getElementNames(modelClass)) {
if (!ModelSupport.isSummaryElement(modelClass, elementName)) {
continue;
}
elementNames.add(elementName);
}
summaryElementNameMap.put(modelClass, Collections.unmodifiableSet(elementNames));
}
return Collections.unmodifiableMap(summaryElementNameMap);
}
public static Set getElementNames(Class type) {
return ELEMENT_NAME_MAP.getOrDefault(type, Collections.emptySet());
}
public static Set getSummaryElementNames(Class type) {
return Collections.unmodifiableSet(SUMMARY_ELEMENT_NAME_MAP.getOrDefault(type, Collections.emptySet()));
}
public static Set getSummaryDataElementNames(Class type) {
if (SUMMARY_DATA_ELEMENT_NAME_MAP.get(type) != null) {
return Collections.unmodifiableSet(SUMMARY_DATA_ELEMENT_NAME_MAP.get(type));
} else {
Set summaryData = ELEMENT_NAME_MAP.getOrDefault(type, Collections.emptySet())
.stream().filter(e -> !"text".equals(e)).collect(Collectors.toSet());
SUMMARY_DATA_ELEMENT_NAME_MAP.put(type, summaryData);
return summaryData;
}
}
public static Set getRequiredElementNames(Class type) {
return REQUIRED_ELEMENT_NAME_MAP.getOrDefault(type, Collections.emptySet());
}
public static JsonArray getJsonArray(JsonObject jsonObject, String key) {
return getJsonArray(jsonObject, key, false);
}
public static JsonArray getJsonArray(JsonObject jsonObject, String key, boolean primitive) {
JsonArray jsonArray = getJsonValue(jsonObject, key, JsonArray.class);
if (primitive) {
if (jsonArray == null) {
JsonArray _jsonArray = jsonObject.getJsonArray("_" + key);
if (_jsonArray != null) {
throw new IllegalArgumentException("Found array with key '_" + key + "' but could not find matching array with key: '" + key + "'");
}
}
}
return jsonArray;
}
public static JsonValue getJsonValue(JsonArray jsonArray, int index) {
if (jsonArray != null) {
if (index >= 0 && index < jsonArray.size()) {
return jsonArray.get(index);
} else {
throw new IllegalArgumentException("Could not find element at index: " + index);
}
}
return null;
}
public static T getJsonValue(JsonObject jsonObject, String key, Class expectedType) {
JsonValue jsonValue = jsonObject.get(key);
if (jsonValue != null && !expectedType.isInstance(jsonValue)) {
throw new IllegalArgumentException("Expected: " + expectedType.getSimpleName() + " but found: " + jsonValue.getValueType()
+ " for element: " + key);
}
return expectedType.cast(jsonValue);
}
// TODO: replace this method with a class that converts Resource to JsonObject directly
public static JsonObject toJsonObject(Resource resource) throws FHIRGeneratorException {
StringWriter writer = new StringWriter();
FHIRGenerator.generator(Format.JSON).generate(resource, writer);
return JSON_READER_FACTORY.createReader(new StringReader(writer.toString())).readObject();
}
public static Reader nonClosingReader(Reader reader) {
return new FilterReader(reader) {
@Override
public void close() {
// do nothing
}
};
}
public static InputStream nonClosingInputStream(InputStream in) {
return new FilterInputStream(in) {
@Override
public void close() {
// do nothing
}
};
}
public static Writer nonClosingWriter(Writer writer) {
return new FilterWriter(writer) {
@Override
public void close() {
// do nothing
}
};
}
public static OutputStream nonClosingOutputStream(OutputStream out) {
return new FilterOutputStream(out) {
@Override
public void close() {
// do nothing
}
};
}
public static void checkForUnrecognizedElements(Class type, JsonObject jsonObject) {
Set elementNames = JsonSupport.getElementNames(type);
for (java.lang.String key : jsonObject.keySet()) {
if (!elementNames.contains(key) && !"resourceType".equals(key) && !"fhir_comments".equals(key)) {
throw new IllegalArgumentException("Unrecognized element: '" + key + "'");
}
}
}
public static Class getResourceType(JsonObject jsonObject) {
JsonString resourceTypeString = jsonObject.getJsonString("resourceType");
if (resourceTypeString == null) {
throw new IllegalArgumentException("Missing required element: 'resourceType'");
}
String resourceTypeName = resourceTypeString.getString();
Class resourceType = ModelSupport.getResourceType(resourceTypeName);
if (resourceType == null) {
throw new IllegalArgumentException("Invalid resource type: '" + resourceTypeName + "'");
}
return resourceType;
}
}