Make sure we correctly clean up resources
This commit is contained in:
parent
f9bff78a6e
commit
d9c167455e
|
@ -2,6 +2,7 @@ package org.hl7.fhir.dstu2016may.hapi.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.dstu2016may.model.*;
|
||||
import org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent;
|
||||
|
@ -68,8 +69,8 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
Map<String, CodeSystem> codeSystems = myCodeSystems;
|
||||
Map<String, ValueSet> valueSets = myValueSets;
|
||||
if (codeSystems == null) {
|
||||
codeSystems = new HashMap<String, CodeSystem>();
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
codeSystems = new HashMap<>();
|
||||
valueSets = new HashMap<>();
|
||||
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/model/valueset/v2-tables.xml");
|
||||
|
@ -155,27 +156,33 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
InputStreamReader reader = null;
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.r4.hapi.ctx;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
@ -141,27 +142,33 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
InputStreamReader reader = null;
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.hl7.fhir.dstu3.hapi.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
|
||||
|
@ -24,243 +24,249 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
|
||||
public class DefaultProfileValidationSupport implements IValidationSupport {
|
||||
|
||||
private static final String URL_PREFIX_VALUE_SET = "http://hl7.org/fhir/ValueSet/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION = "http://hl7.org/fhir/StructureDefinition/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION_BASE = "http://hl7.org/fhir/";
|
||||
private static final String URL_PREFIX_VALUE_SET = "http://hl7.org/fhir/ValueSet/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION = "http://hl7.org/fhir/StructureDefinition/";
|
||||
private static final String URL_PREFIX_STRUCTURE_DEFINITION_BASE = "http://hl7.org/fhir/";
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DefaultProfileValidationSupport.class);
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DefaultProfileValidationSupport.class);
|
||||
|
||||
private Map<String, CodeSystem> myCodeSystems;
|
||||
private Map<String, StructureDefinition> myStructureDefinitions;
|
||||
private Map<String, ValueSet> myValueSets;
|
||||
private Map<String, CodeSystem> myCodeSystems;
|
||||
private Map<String, StructureDefinition> myStructureDefinitions;
|
||||
private Map<String, ValueSet> myValueSets;
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
|
||||
ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
|
||||
ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
|
||||
|
||||
Set<String> wantCodes = new HashSet<String>();
|
||||
for (ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||
wantCodes.add(next.getCode());
|
||||
}
|
||||
Set<String> wantCodes = new HashSet<>();
|
||||
for (ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||
wantCodes.add(next.getCode());
|
||||
}
|
||||
|
||||
CodeSystem system = fetchCodeSystem(theContext, theInclude.getSystem());
|
||||
for (ConceptDefinitionComponent next : system.getConcept()) {
|
||||
if (wantCodes.isEmpty() || wantCodes.contains(next.getCode())) {
|
||||
retVal.addContains().setSystem(theInclude.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
|
||||
}
|
||||
}
|
||||
CodeSystem system = fetchCodeSystem(theContext, theInclude.getSystem());
|
||||
for (ConceptDefinitionComponent next : system.getConcept()) {
|
||||
if (wantCodes.isEmpty() || wantCodes.contains(next.getCode())) {
|
||||
retVal.addContains().setSystem(theInclude.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IBaseResource> fetchAllConformanceResources(FhirContext theContext) {
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<>();
|
||||
retVal.addAll(myCodeSystems.values());
|
||||
retVal.addAll(myStructureDefinitions.values());
|
||||
retVal.addAll(myValueSets.values());
|
||||
return retVal;
|
||||
}
|
||||
@Override
|
||||
public List<IBaseResource> fetchAllConformanceResources(FhirContext theContext) {
|
||||
ArrayList<IBaseResource> retVal = new ArrayList<>();
|
||||
retVal.addAll(myCodeSystems.values());
|
||||
retVal.addAll(myStructureDefinitions.values());
|
||||
retVal.addAll(myValueSets.values());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {
|
||||
return new ArrayList<StructureDefinition>(provideStructureDefinitionMap(theContext).values());
|
||||
}
|
||||
@Override
|
||||
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {
|
||||
return new ArrayList<StructureDefinition>(provideStructureDefinitionMap(theContext).values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
|
||||
return (CodeSystem) fetchCodeSystemOrValueSet(theContext, theSystem, true);
|
||||
}
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
|
||||
return (CodeSystem) fetchCodeSystemOrValueSet(theContext, theSystem, true);
|
||||
}
|
||||
|
||||
private DomainResource fetchCodeSystemOrValueSet(FhirContext theContext, String theSystem, boolean codeSystem) {
|
||||
synchronized (this) {
|
||||
Map<String, CodeSystem> codeSystems = myCodeSystems;
|
||||
Map<String, ValueSet> valueSets = myValueSets;
|
||||
if (codeSystems == null || valueSets == null) {
|
||||
codeSystems = new HashMap<String, CodeSystem>();
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
private DomainResource fetchCodeSystemOrValueSet(FhirContext theContext, String theSystem, boolean codeSystem) {
|
||||
synchronized (this) {
|
||||
Map<String, CodeSystem> codeSystems = myCodeSystems;
|
||||
Map<String, ValueSet> valueSets = myValueSets;
|
||||
if (codeSystems == null || valueSets == null) {
|
||||
codeSystems = new HashMap<String, CodeSystem>();
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v3-codesystems.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v3-codesystems.xml");
|
||||
|
||||
myCodeSystems = codeSystems;
|
||||
myValueSets = valueSets;
|
||||
}
|
||||
myCodeSystems = codeSystems;
|
||||
myValueSets = valueSets;
|
||||
}
|
||||
|
||||
if (codeSystem) {
|
||||
return codeSystems.get(theSystem);
|
||||
} else {
|
||||
return valueSets.get(theSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (codeSystem) {
|
||||
return codeSystems.get(theSystem);
|
||||
} else {
|
||||
return valueSets.get(theSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
Validate.notBlank(theUri, "theUri must not be null or blank");
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
Validate.notBlank(theUri, "theUri must not be null or blank");
|
||||
|
||||
if (theClass.equals(StructureDefinition.class)) {
|
||||
return (T) fetchStructureDefinition(theContext, theUri);
|
||||
}
|
||||
if (theClass.equals(StructureDefinition.class)) {
|
||||
return (T) fetchStructureDefinition(theContext, theUri);
|
||||
}
|
||||
|
||||
if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
|
||||
return (T) fetchValueSet(theContext, theUri);
|
||||
}
|
||||
if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
|
||||
return (T) fetchValueSet(theContext, theUri);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition fetchStructureDefinition(FhirContext theContext, String theUrl) {
|
||||
String url = theUrl;
|
||||
if (url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
// no change
|
||||
} else if (url.indexOf('/') == -1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION + url;
|
||||
} else if (StringUtils.countMatches(url, '/') == 1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION_BASE + url;
|
||||
}
|
||||
Map<String, StructureDefinition> map = provideStructureDefinitionMap(theContext);
|
||||
StructureDefinition retVal = map.get(url);
|
||||
@Override
|
||||
public StructureDefinition fetchStructureDefinition(FhirContext theContext, String theUrl) {
|
||||
String url = theUrl;
|
||||
if (url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
// no change
|
||||
} else if (url.indexOf('/') == -1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION + url;
|
||||
} else if (StringUtils.countMatches(url, '/') == 1) {
|
||||
url = URL_PREFIX_STRUCTURE_DEFINITION_BASE + url;
|
||||
}
|
||||
Map<String, StructureDefinition> map = provideStructureDefinitionMap(theContext);
|
||||
StructureDefinition retVal = map.get(url);
|
||||
|
||||
if (retVal == null && url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
String tryUrl = URL_PREFIX_STRUCTURE_DEFINITION + StringUtils.capitalize(url.substring(URL_PREFIX_STRUCTURE_DEFINITION.length()));
|
||||
retVal = map.get(tryUrl);
|
||||
}
|
||||
if (retVal == null && url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
|
||||
String tryUrl = URL_PREFIX_STRUCTURE_DEFINITION + StringUtils.capitalize(url.substring(URL_PREFIX_STRUCTURE_DEFINITION.length()));
|
||||
retVal = map.get(tryUrl);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
ValueSet fetchValueSet(FhirContext theContext, String theSystem) {
|
||||
return (ValueSet) fetchCodeSystemOrValueSet(theContext, theSystem, false);
|
||||
}
|
||||
ValueSet fetchValueSet(FhirContext theContext, String theSystem) {
|
||||
return (ValueSet) fetchCodeSystemOrValueSet(theContext, theSystem, false);
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
myCodeSystems = null;
|
||||
myStructureDefinitions = null;
|
||||
}
|
||||
public void flush() {
|
||||
myCodeSystems = null;
|
||||
myStructureDefinitions = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theSystem);
|
||||
return cs != null && cs.getContent() != CodeSystemContentMode.NOTPRESENT;
|
||||
}
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theSystem);
|
||||
return cs != null && cs.getContent() != CodeSystemContentMode.NOTPRESENT;
|
||||
}
|
||||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {
|
||||
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
|
||||
InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
InputStreamReader reader = null;
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
reader = new InputStreamReader(inputStream, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof CodeSystem) {
|
||||
CodeSystem nextValueSet = (CodeSystem) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextValueSet);
|
||||
}
|
||||
} else if (next.getResource() instanceof ValueSet) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
nextValueSet.getText().setDivAsString("");
|
||||
String system = nextValueSet.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadStructureDefinitions(FhirContext theContext, Map<String, StructureDefinition> theCodeSystems, String theClasspath) {
|
||||
ourLog.info("Loading structure definitions from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
private void loadStructureDefinitions(FhirContext theContext, Map<String, StructureDefinition> theCodeSystems, String theClasspath) {
|
||||
ourLog.info("Loading structure definitions from classpath: {}", theClasspath);
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
|
||||
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof StructureDefinition) {
|
||||
StructureDefinition nextSd = (StructureDefinition) next.getResource();
|
||||
nextSd.getText().setDivAsString("");
|
||||
String system = nextSd.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextSd);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
if (next.getResource() instanceof StructureDefinition) {
|
||||
StructureDefinition nextSd = (StructureDefinition) next.getResource();
|
||||
nextSd.getText().setDivAsString("");
|
||||
String system = nextSd.getUrl();
|
||||
if (isNotBlank(system)) {
|
||||
theCodeSystems.put(system, nextSd);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ourLog.warn("Unable to load resource: {}", theClasspath);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, StructureDefinition> provideStructureDefinitionMap(FhirContext theContext) {
|
||||
Map<String, StructureDefinition> structureDefinitions = myStructureDefinitions;
|
||||
if (structureDefinitions == null) {
|
||||
structureDefinitions = new HashMap<String, StructureDefinition>();
|
||||
private Map<String, StructureDefinition> provideStructureDefinitionMap(FhirContext theContext) {
|
||||
Map<String, StructureDefinition> structureDefinitions = myStructureDefinitions;
|
||||
if (structureDefinitions == null) {
|
||||
structureDefinitions = new HashMap<String, StructureDefinition>();
|
||||
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-resources.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-types.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-others.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-resources.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-types.xml");
|
||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-others.xml");
|
||||
|
||||
myStructureDefinitions = structureDefinitions;
|
||||
}
|
||||
return structureDefinitions;
|
||||
}
|
||||
myStructureDefinitions = structureDefinitions;
|
||||
}
|
||||
return structureDefinitions;
|
||||
}
|
||||
|
||||
private CodeValidationResult testIfConceptIsInList(String theCode, List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive) {
|
||||
String code = theCode;
|
||||
if (theCaseSensitive == false) {
|
||||
code = code.toUpperCase();
|
||||
}
|
||||
private CodeValidationResult testIfConceptIsInList(String theCode, List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive) {
|
||||
String code = theCode;
|
||||
if (theCaseSensitive == false) {
|
||||
code = code.toUpperCase();
|
||||
}
|
||||
|
||||
return testIfConceptIsInListInner(conceptList, theCaseSensitive, code);
|
||||
}
|
||||
return testIfConceptIsInListInner(conceptList, theCaseSensitive, code);
|
||||
}
|
||||
|
||||
private CodeValidationResult testIfConceptIsInListInner(List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive, String code) {
|
||||
CodeValidationResult retVal = null;
|
||||
for (ConceptDefinitionComponent next : conceptList) {
|
||||
String nextCandidate = next.getCode();
|
||||
if (theCaseSensitive == false) {
|
||||
nextCandidate = nextCandidate.toUpperCase();
|
||||
}
|
||||
if (nextCandidate.equals(code)) {
|
||||
retVal = new CodeValidationResult(next);
|
||||
break;
|
||||
}
|
||||
private CodeValidationResult testIfConceptIsInListInner(List<ConceptDefinitionComponent> conceptList, boolean theCaseSensitive, String code) {
|
||||
CodeValidationResult retVal = null;
|
||||
for (ConceptDefinitionComponent next : conceptList) {
|
||||
String nextCandidate = next.getCode();
|
||||
if (theCaseSensitive == false) {
|
||||
nextCandidate = nextCandidate.toUpperCase();
|
||||
}
|
||||
if (nextCandidate.equals(code)) {
|
||||
retVal = new CodeValidationResult(next);
|
||||
break;
|
||||
}
|
||||
|
||||
// recurse
|
||||
retVal = testIfConceptIsInList(code, next.getConcept(), theCaseSensitive);
|
||||
if (retVal != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// recurse
|
||||
retVal = testIfConceptIsInList(code, next.getConcept(), theCaseSensitive);
|
||||
if (retVal != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
|
||||
if (cs != null) {
|
||||
boolean caseSensitive = true;
|
||||
if (cs.hasCaseSensitive()) {
|
||||
caseSensitive = cs.getCaseSensitive();
|
||||
}
|
||||
@Override
|
||||
public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
|
||||
CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
|
||||
if (cs != null) {
|
||||
boolean caseSensitive = true;
|
||||
if (cs.hasCaseSensitive()) {
|
||||
caseSensitive = cs.getCaseSensitive();
|
||||
}
|
||||
|
||||
CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
|
||||
CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
|
||||
|
||||
if (retVal != null) {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
if (retVal != null) {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
|
||||
}
|
||||
return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.hl7.fhir.instance.hapi.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.Bundle;
|
||||
import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.instance.model.CodeType;
|
||||
|
@ -44,9 +45,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
if (valueSets == null) {
|
||||
valueSets = new HashMap<String, ValueSet>();
|
||||
|
||||
loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/valuesets.xml");
|
||||
loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v2-tables.xml");
|
||||
loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v3-codesystems.xml");
|
||||
loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/valuesets.xml");
|
||||
loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v2-tables.xml");
|
||||
loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v3-codesystems.xml");
|
||||
|
||||
myCodeSystems = valueSets;
|
||||
}
|
||||
|
@ -108,26 +109,34 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void loadCodeSystems(FhirContext theContext, Map<String, ValueSet> codeSystems, String file) {
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(file);
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader;
|
||||
try {
|
||||
reader = new InputStreamReader(valuesetText, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Shouldn't happen!
|
||||
throw new InternalErrorException("UTF-8 encoding not supported on this platform", e);
|
||||
}
|
||||
private void loadValueSets(FhirContext theContext, Map<String, ValueSet> theValueSets, String theFile) {
|
||||
InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theFile);
|
||||
try {
|
||||
if (valuesetText != null) {
|
||||
InputStreamReader reader = null;
|
||||
try {
|
||||
reader = new InputStreamReader(valuesetText, "UTF-8");
|
||||
|
||||
FhirContext ctx = FhirInstanceValidator.getHl7OrgDstu2Ctx(theContext);
|
||||
Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
String system = nextValueSet.getCodeSystem().getSystem();
|
||||
if (isNotBlank(system)) {
|
||||
codeSystems.put(system, nextValueSet);
|
||||
FhirContext ctx = FhirInstanceValidator.getHl7OrgDstu2Ctx(theContext);
|
||||
Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, reader);
|
||||
for (BundleEntryComponent next : bundle.getEntry()) {
|
||||
ValueSet nextValueSet = (ValueSet) next.getResource();
|
||||
String system = nextValueSet.getCodeSystem().getSystem();
|
||||
if (isNotBlank(system)) {
|
||||
theValueSets.put(system, nextValueSet);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Shouldn't happen!
|
||||
throw new InternalErrorException("UTF-8 encoding not supported on this platform", e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
}
|
||||
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(valuesetText);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +145,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
|||
ValueSet vs = fetchCodeSystem(theContext, theCodeSystem);
|
||||
if (vs != null) {
|
||||
for (ValueSet.ConceptDefinitionComponent nextConcept : vs.getCodeSystem().getConcept()) {
|
||||
if (nextConcept.getCode().equals(theCode)){
|
||||
if (nextConcept.getCode().equals(theCode)) {
|
||||
ValueSet.ConceptDefinitionComponent component = new ValueSet.ConceptDefinitionComponent(new CodeType(theCode));
|
||||
return new CodeValidationResult(component);
|
||||
}
|
||||
|
|
|
@ -297,6 +297,13 @@
|
|||
Suport for the :contains string search parameter modifier has been added to
|
||||
the JPA server. Thanks to Anthony Sute for the pull request!
|
||||
</action>
|
||||
<action type="fix">
|
||||
All instances of DefaultProfileValidationSupport (i.e. one for
|
||||
each version of FHIR) have been fixed so that they explicitly
|
||||
close any InputStreams they open in order to read the built-in
|
||||
profile resources. Leaving these open caused resource starvation
|
||||
in some cases under heavy load.
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.2.0" date="2018-01-13">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue