Second pull request for fixes for issue #1048.
This commit is contained in:
parent
3cf3f7d5d6
commit
0fdcad0985
|
@ -1,6 +1,12 @@
|
||||||
package org.hl7.fhir.instance.hapi.validation;
|
package org.hl7.fhir.instance.hapi.validation;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.*;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.validation.IValidationContext;
|
import ca.uhn.fhir.validation.IValidationContext;
|
||||||
|
@ -10,6 +16,8 @@ import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
@ -20,7 +28,12 @@ import org.hl7.fhir.convertors.VersionConvertorAdvisor40;
|
||||||
import org.hl7.fhir.convertors.VersionConvertor_10_40;
|
import org.hl7.fhir.convertors.VersionConvertor_10_40;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||||
import org.hl7.fhir.instance.model.*;
|
import org.hl7.fhir.instance.model.CodeableConcept;
|
||||||
|
import org.hl7.fhir.instance.model.Coding;
|
||||||
|
import org.hl7.fhir.instance.model.Questionnaire;
|
||||||
|
import org.hl7.fhir.instance.model.Resource;
|
||||||
|
import org.hl7.fhir.instance.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.instance.model.ValueSet;
|
||||||
import org.hl7.fhir.r4.context.IWorkerContext;
|
import org.hl7.fhir.r4.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r4.formats.IParser;
|
import org.hl7.fhir.r4.formats.IParser;
|
||||||
import org.hl7.fhir.r4.formats.ParserType;
|
import org.hl7.fhir.r4.formats.ParserType;
|
||||||
|
@ -40,15 +53,18 @@ import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
|
||||||
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
|
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
|
||||||
|
|
||||||
|
@ -128,6 +144,28 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
|
||||||
return root.getLocalName();
|
return root.getLocalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> determineIfProfilesSpecified(Document theDocument)
|
||||||
|
{
|
||||||
|
ArrayList<String> profileNames = new ArrayList<String>();
|
||||||
|
NodeList list = theDocument.getChildNodes().item(0).getChildNodes();
|
||||||
|
for (int i = 0; i < list.getLength(); i++) {
|
||||||
|
if (list.item(i).getNodeName().compareToIgnoreCase("meta") == 0)
|
||||||
|
{
|
||||||
|
NodeList metaList = list.item(i).getChildNodes();
|
||||||
|
for (int j = 0; j < metaList.getLength(); j++)
|
||||||
|
{
|
||||||
|
if (metaList.item(j).getNodeName().compareToIgnoreCase("profile") == 0)
|
||||||
|
{
|
||||||
|
String[] components = metaList.item(j).getAttributes().item(0).getNodeValue().split("/");
|
||||||
|
profileNames.add(components[components.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return profileNames;
|
||||||
|
}
|
||||||
|
|
||||||
private StructureDefinition findStructureDefinitionForResourceName(final FhirContext theCtx, String resourceName) {
|
private StructureDefinition findStructureDefinitionForResourceName(final FhirContext theCtx, String resourceName) {
|
||||||
String sdName = "http://hl7.org/fhir/StructureDefinition/" + resourceName;
|
String sdName = "http://hl7.org/fhir/StructureDefinition/" + resourceName;
|
||||||
StructureDefinition profile = myStructureDefintion != null ? myStructureDefintion : myValidationSupport.fetchResource(theCtx, StructureDefinition.class, sdName);
|
StructureDefinition profile = myStructureDefintion != null ? myStructureDefintion : myValidationSupport.fetchResource(theCtx, StructureDefinition.class, sdName);
|
||||||
|
@ -257,27 +295,49 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
|
||||||
return Collections.singletonList(m);
|
return Collections.singletonList(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
String resourceName = determineResourceName(document);
|
// Determine if meta/profiles are present...
|
||||||
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
ArrayList<String> resourceNames = determineIfProfilesSpecified(document);
|
||||||
if (profile != null) {
|
if (resourceNames.isEmpty())
|
||||||
try {
|
{
|
||||||
v.validate(null, messages, document, profile.getUrl());
|
resourceNames.add(determineResourceName(document));
|
||||||
} catch (Exception e) {
|
}
|
||||||
ourLog.error("Failure during validation", e);
|
|
||||||
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
for (String resourceName : resourceNames) {
|
||||||
|
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
v.validate(null, messages, document, profile.getUrl());
|
||||||
|
} catch (Exception e) {
|
||||||
|
ourLog.error("Failure during validation", e);
|
||||||
|
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (theEncoding == EncodingEnum.JSON) {
|
} else if (theEncoding == EncodingEnum.JSON) {
|
||||||
Gson gson = new GsonBuilder().create();
|
Gson gson = new GsonBuilder().create();
|
||||||
JsonObject json = gson.fromJson(theInput, JsonObject.class);
|
JsonObject json = gson.fromJson(theInput, JsonObject.class);
|
||||||
|
|
||||||
String resourceName = json.get("resourceType").getAsString();
|
ArrayList<String> resourceNames = new ArrayList<String>();
|
||||||
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
JsonArray profiles = null;
|
||||||
if (profile != null) {
|
try {
|
||||||
try {
|
profiles = json.getAsJsonObject("meta").getAsJsonArray("profile");
|
||||||
v.validate(null, messages, json, profile.getUrl());
|
for (JsonElement element : profiles)
|
||||||
} catch (Exception e) {
|
{
|
||||||
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
String[] components = element.getAsString().split("/");
|
||||||
|
resourceNames.add(components[components.length - 1]);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
resourceNames.add(json.get("resourceType").getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String resourceName : resourceNames) {
|
||||||
|
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
v.validate(null, messages, json, profile.getUrl());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
package org.hl7.fhir.r4.hapi.validation;
|
package org.hl7.fhir.r4.hapi.validation;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import java.util.*;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import ca.uhn.fhir.validation.IValidationContext;
|
||||||
|
import ca.uhn.fhir.validation.IValidatorModule;
|
||||||
|
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 org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.exceptions.PathEngineException;
|
import org.hl7.fhir.exceptions.PathEngineException;
|
||||||
import org.hl7.fhir.r4.hapi.ctx.*;
|
import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
|
||||||
|
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
|
||||||
|
import org.hl7.fhir.r4.model.Base;
|
||||||
|
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.r4.model.TypeDetails;
|
||||||
import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
import org.hl7.fhir.r4.utils.IResourceValidator.BestPracticeWarningLevel;
|
import org.hl7.fhir.r4.utils.IResourceValidator.BestPracticeWarningLevel;
|
||||||
import org.hl7.fhir.r4.utils.IResourceValidator.IdStatus;
|
import org.hl7.fhir.r4.utils.IResourceValidator.IdStatus;
|
||||||
|
@ -21,14 +30,13 @@ import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
import com.google.gson.*;
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|
||||||
import ca.uhn.fhir.validation.IValidationContext;
|
|
||||||
import ca.uhn.fhir.validation.IValidatorModule;
|
|
||||||
|
|
||||||
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
|
public class FhirInstanceValidator extends BaseValidatorBridge implements IValidatorModule {
|
||||||
|
|
||||||
|
@ -77,6 +85,28 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
|
||||||
return root.getLocalName();
|
return root.getLocalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> determineIfProfilesSpecified(Document theDocument)
|
||||||
|
{
|
||||||
|
ArrayList<String> profileNames = new ArrayList<String>();
|
||||||
|
NodeList list = theDocument.getChildNodes().item(0).getChildNodes();
|
||||||
|
for (int i = 0; i < list.getLength(); i++) {
|
||||||
|
if (list.item(i).getNodeName().compareToIgnoreCase("meta") == 0)
|
||||||
|
{
|
||||||
|
NodeList metaList = list.item(i).getChildNodes();
|
||||||
|
for (int j = 0; j < metaList.getLength(); j++)
|
||||||
|
{
|
||||||
|
if (metaList.item(j).getNodeName().compareToIgnoreCase("profile") == 0)
|
||||||
|
{
|
||||||
|
String[] components = metaList.item(j).getAttributes().item(0).getNodeValue().split("/");
|
||||||
|
profileNames.add(components[components.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return profileNames;
|
||||||
|
}
|
||||||
|
|
||||||
private StructureDefinition findStructureDefinitionForResourceName(final FhirContext theCtx, String resourceName) {
|
private StructureDefinition findStructureDefinitionForResourceName(final FhirContext theCtx, String resourceName) {
|
||||||
String sdName = "http://hl7.org/fhir/StructureDefinition/" + resourceName;
|
String sdName = "http://hl7.org/fhir/StructureDefinition/" + resourceName;
|
||||||
StructureDefinition profile = myStructureDefintion != null ? myStructureDefintion : myValidationSupport.fetchStructureDefinition(theCtx, sdName);
|
StructureDefinition profile = myStructureDefintion != null ? myStructureDefintion : myValidationSupport.fetchStructureDefinition(theCtx, sdName);
|
||||||
|
@ -200,27 +230,49 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
|
||||||
return Collections.singletonList(m);
|
return Collections.singletonList(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
String resourceName = determineResourceName(document);
|
// Determine if meta/profiles are present...
|
||||||
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
ArrayList<String> resourceNames = determineIfProfilesSpecified(document);
|
||||||
if (profile != null) {
|
if (resourceNames.isEmpty())
|
||||||
try {
|
{
|
||||||
v.validate(null, messages, document, profile);
|
resourceNames.add(determineResourceName(document));
|
||||||
} catch (Exception e) {
|
}
|
||||||
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
|
||||||
|
for (String resourceName : resourceNames) {
|
||||||
|
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
v.validate(null, messages, document, profile.getUrl());
|
||||||
|
} catch (Exception e) {
|
||||||
|
ourLog.error("Failure during validation", e);
|
||||||
|
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (theEncoding == EncodingEnum.JSON) {
|
} else if (theEncoding == EncodingEnum.JSON) {
|
||||||
Gson gson = new GsonBuilder().create();
|
Gson gson = new GsonBuilder().create();
|
||||||
JsonObject json = gson.fromJson(theInput, JsonObject.class);
|
JsonObject json = gson.fromJson(theInput, JsonObject.class);
|
||||||
|
|
||||||
String resourceName = json.get("resourceType").getAsString();
|
ArrayList<String> resourceNames = new ArrayList<String>();
|
||||||
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
JsonArray profiles = null;
|
||||||
if (profile != null) {
|
try {
|
||||||
try {
|
profiles = json.getAsJsonObject("meta").getAsJsonArray("profile");
|
||||||
v.validate(null, messages, json, profile);
|
for (JsonElement element : profiles)
|
||||||
} catch (Exception e) {
|
{
|
||||||
ourLog.error("Failure during validation", e);
|
String[] components = element.getAsString().split("/");
|
||||||
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
resourceNames.add(components[components.length - 1]);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
resourceNames.add(json.get("resourceType").getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String resourceName : resourceNames) {
|
||||||
|
StructureDefinition profile = findStructureDefinitionForResourceName(theCtx, resourceName);
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
v.validate(null, messages, json, profile.getUrl());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InternalErrorException("Unexpected failure while validating resource", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue