Cleanup of validator

This commit is contained in:
James Agnew 2017-09-09 20:55:00 -07:00
parent 736e037b1a
commit 2bb01451ea
63 changed files with 7878 additions and 9408 deletions

View File

@ -8,6 +8,7 @@ import javax.servlet.ServletException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.*;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;

View File

@ -2,7 +2,7 @@ package example;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
import ca.uhn.fhir.context.FhirContext;

View File

@ -1,28 +1,8 @@
package ca.uhn.fhir.cli;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.cli.*;
import org.apache.commons.io.*;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.fusesource.jansi.Ansi;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.Bundle.*;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
@ -39,11 +19,280 @@ import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.ResourceReferenceInfo;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class ExampleDataUploader extends BaseCommand {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleDataUploader.class);
private IBaseBundle getBundleFromFile(Integer theLimit, File theSuppliedFile, FhirContext theCtx) throws ParseException, IOException {
switch (theCtx.getVersion().getVersion()) {
case DSTU2:
return getBundleFromFileDstu2(theLimit, theSuppliedFile, theCtx);
case DSTU3:
return getBundleFromFileDstu3(theLimit, theSuppliedFile, theCtx);
case R4:
return getBundleFromFileR4(theLimit, theSuppliedFile, theCtx);
default:
throw new ParseException("Invalid spec version for this command: " + theCtx.getVersion().getVersion());
}
}
private Bundle getBundleFromFileDstu2(Integer limit, File inputFile, FhirContext ctx) throws IOException, UnsupportedEncodingException {
Bundle bundle = new Bundle();
ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile));
byte[] buffer = new byte[2048];
int count = 0;
while (true) {
count++;
if (limit != null && count > limit) {
break;
}
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry == null) {
break;
}
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = zis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] exampleBytes = bos.toByteArray();
String exampleString = new String(exampleBytes, "UTF-8");
if (ourLog.isTraceEnabled()) {
ourLog.trace("Next example: " + exampleString);
}
IBaseResource parsed;
try {
parsed = ctx.newJsonParser().parseResource(exampleString);
} catch (DataFormatException e) {
ourLog.info("FAILED to parse example {}", nextEntry.getName(), e);
continue;
}
ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length());
if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) {
BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry");
BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
for (IBase nextEntry1 : entryChildDef.getAccessor().getValues(parsed)) {
List<IBase> resources = entryDef.getChildByName("resource").getAccessor().getValues(nextEntry1);
if (resources == null) {
continue;
}
for (IBase nextResource : resources) {
if (!ctx.getResourceDefinition(parsed).getName().equals("Bundle") && ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
bundle.addEntry().setRequest(new EntryRequest().setMethod(HTTPVerbEnum.POST)).setResource((IResource) nextResource);
}
}
}
} else {
if (ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
continue;
}
bundle.addEntry().setRequest(new EntryRequest().setMethod(HTTPVerbEnum.POST)).setResource((IResource) parsed);
}
}
return bundle;
}
@SuppressWarnings("unchecked")
private org.hl7.fhir.dstu3.model.Bundle getBundleFromFileDstu3(Integer limit, File inputFile, FhirContext ctx) throws IOException, UnsupportedEncodingException {
org.hl7.fhir.dstu3.model.Bundle bundle = new org.hl7.fhir.dstu3.model.Bundle();
bundle.setType(BundleType.TRANSACTION);
FhirValidator val = ctx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator(new DefaultProfileValidationSupport()));
ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile));
byte[] buffer = new byte[2048];
int count = 0;
while (true) {
count++;
if (limit != null && count > limit) {
break;
}
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry == null) {
break;
}
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = zis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] exampleBytes = bos.toByteArray();
String exampleString = new String(exampleBytes, "UTF-8");
if (ourLog.isTraceEnabled()) {
ourLog.trace("Next example: " + exampleString);
}
IBaseResource parsed;
try {
parsed = ctx.newJsonParser().parseResource(exampleString);
} catch (Exception e) {
ourLog.info("FAILED to parse example {}", nextEntry.getName(), e);
continue;
}
ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length());
ValidationResult result = val.validateWithResult(parsed);
if (result.isSuccessful() == false) {
ourLog.info("FAILED to validate example {} - {}", nextEntry.getName(), result.toString());
continue;
}
if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) {
BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry");
BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
for (IBase nextEntry1 : entryChildDef.getAccessor().getValues(parsed)) {
List<IBase> resources = entryDef.getChildByName("resource").getAccessor().getValues(nextEntry1);
if (resources == null) {
continue;
}
for (IBase nextResource : resources) {
if (nextResource == null) {
continue;
}
if (!ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("Bundle")
&& ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("SearchParameter")) {
BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(HTTPVerb.POST);
entry.setResource((Resource) nextResource);
}
}
}
} else {
if (ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
continue;
}
BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(HTTPVerb.POST);
entry.setResource((Resource) parsed);
}
}
return bundle;
}
@SuppressWarnings("unchecked")
private org.hl7.fhir.r4.model.Bundle getBundleFromFileR4(Integer limit, File inputFile, FhirContext ctx) throws IOException, UnsupportedEncodingException {
org.hl7.fhir.r4.model.Bundle bundle = new org.hl7.fhir.r4.model.Bundle();
bundle.setType(org.hl7.fhir.r4.model.Bundle.BundleType.TRANSACTION);
FhirValidator val = ctx.newValidator();
val.registerValidatorModule(new org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator(new org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport()));
ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile));
byte[] buffer = new byte[2048];
int count = 0;
while (true) {
count++;
if (limit != null && count > limit) {
break;
}
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry == null) {
break;
}
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = zis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] exampleBytes = bos.toByteArray();
String exampleString = new String(exampleBytes, "UTF-8");
if (ourLog.isTraceEnabled()) {
ourLog.trace("Next example: " + exampleString);
}
IBaseResource parsed;
try {
parsed = ctx.newJsonParser().parseResource(exampleString);
} catch (Exception e) {
ourLog.info("FAILED to parse example {}", nextEntry.getName(), e);
continue;
}
ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length());
ValidationResult result = val.validateWithResult(parsed);
if (result.isSuccessful() == false) {
ourLog.info("FAILED to validate example {} - {}", nextEntry.getName(), result.toString());
continue;
}
if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) {
BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry");
BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
for (IBase nextEntry1 : entryChildDef.getAccessor().getValues(parsed)) {
List<IBase> resources = entryDef.getChildByName("resource").getAccessor().getValues(nextEntry1);
if (resources == null) {
continue;
}
for (IBase nextResource : resources) {
if (nextResource == null) {
continue;
}
if (!ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("Bundle")
&& ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("SearchParameter")) {
org.hl7.fhir.r4.model.Bundle.BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST);
entry.setResource((org.hl7.fhir.r4.model.Resource) nextResource);
}
}
}
} else {
if (ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
continue;
}
org.hl7.fhir.r4.model.Bundle.BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST);
entry.setResource((org.hl7.fhir.r4.model.Resource) parsed);
}
}
return bundle;
}
@Override
public String getCommandDescription() {
return "Downloads the resource example pack from the HL7.org FHIR specification website, and uploads all of the example resources to a given server.";
@ -78,182 +327,9 @@ public class ExampleDataUploader extends BaseCommand {
opt.setRequired(false);
options.addOption(opt);
// opt = new Option("c", "cache", true, "Store a copy of the downloaded example pack on the local disk using a file of the given name. Use this file instead of fetching it from the internet if
// the file already exists.");
// opt.setRequired(false);
// options.addOption(opt);
return options;
}
@Override
public void run(CommandLine theCommandLine) throws Exception {
FhirContext ctx = getSpecVersionContext(theCommandLine);
String targetServer = theCommandLine.getOptionValue("t");
if (isBlank(targetServer)) {
throw new ParseException("No target server (-t) specified");
} else if (targetServer.startsWith("http") == false && targetServer.startsWith("file") == false) {
throw new ParseException("Invalid target server specified, must begin with 'http' or 'file'");
}
Integer limit = null;
String limitString = theCommandLine.getOptionValue('l');
if (isNotBlank(limitString)) {
try {
limit = Integer.parseInt(limitString);
} catch (NumberFormatException e) {
throw new ParseException("Invalid number for limit (-l) option, must be a number: " + limitString);
}
}
String specUrl;
switch (ctx.getVersion().getVersion()) {
case DSTU2:
specUrl = "http://hl7.org/fhir/dstu2/examples-json.zip";
break;
case DSTU3:
specUrl = "http://hl7.org/fhir/STU3/examples-json.zip";
break;
case R4:
specUrl = "http://build.fhir.org/examples-json.zip";
break;
default:
throw new ParseException("Invalid spec version for this command: " + ctx.getVersion().getVersion());
}
String filepath = theCommandLine.getOptionValue('d');
boolean cacheFile = theCommandLine.hasOption('c');
Collection<File> inputFiles = loadFile(ctx, specUrl, filepath, cacheFile);
for (File inputFile : inputFiles) {
IBaseBundle bundle = getBundleFromFile(limit, inputFile, ctx);
processBundle(ctx, bundle);
sendBundleToTarget(targetServer, ctx, bundle);
}
}
private IBaseBundle getBundleFromFile(Integer theLimit, File theSuppliedFile, FhirContext theCtx) throws ParseException, IOException {
switch (theCtx.getVersion().getVersion()) {
case DSTU2:
return getBundleFromFileDstu2(theLimit, theSuppliedFile, theCtx);
case DSTU3:
return getBundleFromFileDstu3(theLimit, theSuppliedFile, theCtx);
case R4:
return getBundleFromFileR4(theLimit, theSuppliedFile, theCtx);
default:
throw new ParseException("Invalid spec version for this command: " + theCtx.getVersion().getVersion());
}
}
private void sendBundleToTarget(String targetServer, FhirContext ctx, IBaseBundle bundle) throws Exception {
List<IBaseResource> resources = BundleUtil.toListOfResources(ctx, bundle);
for (Iterator<IBaseResource> iter = resources.iterator(); iter.hasNext(); ) {
IBaseResource next = iter.next();
String nextType = ctx.getResourceDefinition(next).getName();
if (nextType.endsWith("Definition")) {
iter.remove();
} else if (nextType.contains("ValueSet")) {
iter.remove();
} else if (nextType.equals("CodeSystem")) {
iter.remove();
}
}
List<IBaseResource> subResourceList = new ArrayList<>();
while (resources.size() > 0) {
IBaseResource nextAddedResource = resources.remove(0);
subResourceList.add(nextAddedResource);
Set<String> checkedTargets = new HashSet<>();
for (int i = 0; i < subResourceList.size(); i++) {
IBaseResource nextCandidateSource = subResourceList.get(i);
for (ResourceReferenceInfo nextRef : ctx.newTerser().getAllResourceReferences(nextCandidateSource)) {
String nextRefResourceType = nextRef.getResourceReference().getReferenceElement().getResourceType();
String nextRefIdPart = nextRef.getResourceReference().getReferenceElement().getIdPart();
if (isBlank(nextRefResourceType) || isBlank(nextRefIdPart)) {
nextRef.getResourceReference().setResource(null);
nextRef.getResourceReference().setReference(null);
continue;
}
if (nextRefIdPart.startsWith("EX")) {
nextRefIdPart = nextRefIdPart.substring(2);
}
String nextTarget = nextRefResourceType + "/EX" + nextRefIdPart;
nextRef.getResourceReference().setResource(null);
nextRef.getResourceReference().setReference(nextTarget);
if (checkedTargets.add(nextTarget) == false) {
continue;
}
boolean found = false;
for (int j = 0; j < resources.size(); j++) {
String candidateTarget = resources.get(j).getIdElement().getValue();
if (isNotBlank(nextTarget) && nextTarget.equals(candidateTarget)) {
ourLog.info("Reflexively adding resource {} to bundle as it is a reference target", nextTarget);
subResourceList.add(resources.remove(j));
found = true;
break;
}
}
}
}
if (subResourceList.size() < 10 && resources.size() > 0) {
subResourceList.add(resources.remove(0));
continue;
}
ourLog.info("About to upload {} examples in a transaction, {} remaining", subResourceList.size(), resources.size());
IVersionSpecificBundleFactory bundleFactory = ctx.newBundleFactory();
bundleFactory.initializeBundleFromResourceList(null, subResourceList, null, null, 0, BundleTypeEnum.TRANSACTION);
IBaseResource subBundle = bundleFactory.getResourceBundle();
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(subBundle);
ourLog.info("Final bundle: {}", FileUtils.byteCountToDisplaySize(encoded.length()));
if (targetServer.startsWith("file://")) {
String path = targetServer.substring("file://".length());
ourLog.info("Writing bundle to: {}", path);
File file = new File(path);
if (file.exists()) {
throw new Exception("File already exists: " + file.getAbsolutePath());
}
FileWriter w = new FileWriter(file, false);
w.append(encoded);
w.close();
} else {
ourLog.info("Uploading bundle to server: " + targetServer);
IGenericClient fhirClient = newClient(ctx, targetServer);
fhirClient.registerInterceptor(new GZipContentInterceptor());
long start = System.currentTimeMillis();
try {
fhirClient.transaction().withBundle(encoded).execute();
} catch (BaseServerResponseException e) {
ourLog.error("Failed to upload bundle:HTTP " + e.getStatusCode() + ": " + e.getMessage());
ourLog.error("Failing bundle: {}", encoded);
}
long delay = System.currentTimeMillis() - start;
ourLog.info("Finished uploading bundle to server (took {} ms)", delay);
}
subResourceList.clear();
}
}
private void processBundle(FhirContext ctx, IBaseBundle bundle) {
switch (ctx.getVersion().getVersion()) {
case DSTU2:
@ -496,237 +572,159 @@ public class ExampleDataUploader extends BaseCommand {
}
private Bundle getBundleFromFileDstu2(Integer limit, File inputFile, FhirContext ctx) throws IOException, UnsupportedEncodingException {
@Override
public void run(CommandLine theCommandLine) throws Exception {
FhirContext ctx = getSpecVersionContext(theCommandLine);
Bundle bundle = new Bundle();
String targetServer = theCommandLine.getOptionValue("t");
if (isBlank(targetServer)) {
throw new ParseException("No target server (-t) specified");
} else if (targetServer.startsWith("http") == false && targetServer.startsWith("file") == false) {
throw new ParseException("Invalid target server specified, must begin with 'http' or 'file'");
}
ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile));
byte[] buffer = new byte[2048];
int count = 0;
while (true) {
count++;
if (limit != null && count > limit) {
break;
}
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry == null) {
break;
}
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = zis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] exampleBytes = bos.toByteArray();
String exampleString = new String(exampleBytes, "UTF-8");
if (ourLog.isTraceEnabled()) {
ourLog.trace("Next example: " + exampleString);
}
IBaseResource parsed;
Integer limit = null;
String limitString = theCommandLine.getOptionValue('l');
if (isNotBlank(limitString)) {
try {
parsed = ctx.newJsonParser().parseResource(exampleString);
} catch (DataFormatException e) {
ourLog.info("FAILED to parse example {}", nextEntry.getName(), e);
continue;
}
ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length());
if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) {
BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry");
BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
for (IBase nextEntry1 : entryChildDef.getAccessor().getValues(parsed)) {
List<IBase> resources = entryDef.getChildByName("resource").getAccessor().getValues(nextEntry1);
if (resources == null) {
continue;
}
for (IBase nextResource : resources) {
if (!ctx.getResourceDefinition(parsed).getName().equals("Bundle") && ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
bundle.addEntry().setRequest(new EntryRequest().setMethod(HTTPVerbEnum.POST)).setResource((IResource) nextResource);
}
}
}
} else {
if (ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
continue;
}
bundle.addEntry().setRequest(new EntryRequest().setMethod(HTTPVerbEnum.POST)).setResource((IResource) parsed);
limit = Integer.parseInt(limitString);
} catch (NumberFormatException e) {
throw new ParseException("Invalid number for limit (-l) option, must be a number: " + limitString);
}
}
return bundle;
String specUrl;
switch (ctx.getVersion().getVersion()) {
case DSTU2:
specUrl = "http://hl7.org/fhir/dstu2/examples-json.zip";
break;
case DSTU3:
specUrl = "http://hl7.org/fhir/STU3/examples-json.zip";
break;
case R4:
specUrl = "http://build.fhir.org/examples-json.zip";
break;
default:
throw new ParseException("Invalid spec version for this command: " + ctx.getVersion().getVersion());
}
String filepath = theCommandLine.getOptionValue('d');
boolean cacheFile = theCommandLine.hasOption('c');
Collection<File> inputFiles = loadFile(ctx, specUrl, filepath, cacheFile);
for (File inputFile : inputFiles) {
IBaseBundle bundle = getBundleFromFile(limit, inputFile, ctx);
processBundle(ctx, bundle);
sendBundleToTarget(targetServer, ctx, bundle);
}
}
@SuppressWarnings("unchecked")
private org.hl7.fhir.dstu3.model.Bundle getBundleFromFileDstu3(Integer limit, File inputFile, FhirContext ctx) throws IOException, UnsupportedEncodingException {
private void sendBundleToTarget(String targetServer, FhirContext ctx, IBaseBundle bundle) throws Exception {
List<IBaseResource> resources = BundleUtil.toListOfResources(ctx, bundle);
org.hl7.fhir.dstu3.model.Bundle bundle = new org.hl7.fhir.dstu3.model.Bundle();
bundle.setType(BundleType.TRANSACTION);
for (Iterator<IBaseResource> iter = resources.iterator(); iter.hasNext(); ) {
IBaseResource next = iter.next();
FhirValidator val = ctx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator(new DefaultProfileValidationSupport()));
ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile));
byte[] buffer = new byte[2048];
int count = 0;
while (true) {
count++;
if (limit != null && count > limit) {
break;
}
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry == null) {
break;
}
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = zis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] exampleBytes = bos.toByteArray();
String exampleString = new String(exampleBytes, "UTF-8");
if (ourLog.isTraceEnabled()) {
ourLog.trace("Next example: " + exampleString);
}
IBaseResource parsed;
try {
parsed = ctx.newJsonParser().parseResource(exampleString);
} catch (Exception e) {
ourLog.info("FAILED to parse example {}", nextEntry.getName(), e);
continue;
}
ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length());
ValidationResult result = val.validateWithResult(parsed);
if (result.isSuccessful() == false) {
ourLog.info("FAILED to validate example {} - {}", nextEntry.getName(), result.toString());
continue;
}
if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) {
BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry");
BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
for (IBase nextEntry1 : entryChildDef.getAccessor().getValues(parsed)) {
List<IBase> resources = entryDef.getChildByName("resource").getAccessor().getValues(nextEntry1);
if (resources == null) {
continue;
}
for (IBase nextResource : resources) {
if (nextResource == null) {
continue;
}
if (!ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("Bundle")
&& ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("SearchParameter")) {
BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(HTTPVerb.POST);
entry.setResource((Resource) nextResource);
}
}
}
} else {
if (ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
continue;
}
BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(HTTPVerb.POST);
entry.setResource((Resource) parsed);
String nextType = ctx.getResourceDefinition(next).getName();
if (nextType.endsWith("Definition")) {
iter.remove();
} else if (nextType.contains("ValueSet")) {
iter.remove();
} else if (nextType.equals("CodeSystem")) {
iter.remove();
}
}
return bundle;
}
@SuppressWarnings("unchecked")
private org.hl7.fhir.r4.model.Bundle getBundleFromFileR4(Integer limit, File inputFile, FhirContext ctx) throws IOException, UnsupportedEncodingException {
List<IBaseResource> subResourceList = new ArrayList<>();
while (resources.size() > 0) {
org.hl7.fhir.r4.model.Bundle bundle = new org.hl7.fhir.r4.model.Bundle();
bundle.setType(org.hl7.fhir.r4.model.Bundle.BundleType.TRANSACTION);
IBaseResource nextAddedResource = resources.remove(0);
subResourceList.add(nextAddedResource);
FhirValidator val = ctx.newValidator();
val.registerValidatorModule(new org.hl7.fhir.r4.hapi.validation.FhirInstanceValidator(new org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport()));
Set<String> checkedTargets = new HashSet<>();
ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile));
byte[] buffer = new byte[2048];
int count = 0;
while (true) {
count++;
if (limit != null && count > limit) {
break;
}
ZipEntry nextEntry = zis.getNextEntry();
if (nextEntry == null) {
break;
}
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = zis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
byte[] exampleBytes = bos.toByteArray();
String exampleString = new String(exampleBytes, "UTF-8");
if (ourLog.isTraceEnabled()) {
ourLog.trace("Next example: " + exampleString);
}
IBaseResource parsed;
try {
parsed = ctx.newJsonParser().parseResource(exampleString);
} catch (Exception e) {
ourLog.info("FAILED to parse example {}", nextEntry.getName(), e);
continue;
}
ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length());
ValidationResult result = val.validateWithResult(parsed);
if (result.isSuccessful() == false) {
ourLog.info("FAILED to validate example {} - {}", nextEntry.getName(), result.toString());
continue;
}
if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) {
BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry");
BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
for (IBase nextEntry1 : entryChildDef.getAccessor().getValues(parsed)) {
List<IBase> resources = entryDef.getChildByName("resource").getAccessor().getValues(nextEntry1);
if (resources == null) {
for (int i = 0; i < subResourceList.size(); i++) {
IBaseResource nextCandidateSource = subResourceList.get(i);
for (ResourceReferenceInfo nextRef : ctx.newTerser().getAllResourceReferences(nextCandidateSource)) {
String nextRefResourceType = nextRef.getResourceReference().getReferenceElement().getResourceType();
String nextRefIdPart = nextRef.getResourceReference().getReferenceElement().getIdPart();
if (isBlank(nextRefResourceType) || isBlank(nextRefIdPart)) {
nextRef.getResourceReference().setResource(null);
nextRef.getResourceReference().setReference(null);
continue;
}
for (IBase nextResource : resources) {
if (nextResource == null) {
continue;
}
if (!ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("Bundle")
&& ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("SearchParameter")) {
org.hl7.fhir.r4.model.Bundle.BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST);
entry.setResource((org.hl7.fhir.r4.model.Resource) nextResource);
if (nextRefIdPart.startsWith("EX")) {
nextRefIdPart = nextRefIdPart.substring(2);
}
String nextTarget = nextRefResourceType + "/EX" + nextRefIdPart;
nextRef.getResourceReference().setResource(null);
nextRef.getResourceReference().setReference(nextTarget);
if (checkedTargets.add(nextTarget) == false) {
continue;
}
boolean found = false;
for (int j = 0; j < resources.size(); j++) {
String candidateTarget = resources.get(j).getIdElement().getValue();
if (isNotBlank(nextTarget) && nextTarget.equals(candidateTarget)) {
ourLog.info("Reflexively adding resource {} to bundle as it is a reference target", nextTarget);
subResourceList.add(resources.remove(j));
found = true;
break;
}
}
}
} else {
if (ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) {
continue;
}
org.hl7.fhir.r4.model.Bundle.BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(org.hl7.fhir.r4.model.Bundle.HTTPVerb.POST);
entry.setResource((org.hl7.fhir.r4.model.Resource) parsed);
}
if (subResourceList.size() < 10 && resources.size() > 0) {
subResourceList.add(resources.remove(0));
continue;
}
ourLog.info("About to upload {} examples in a transaction, {} remaining", subResourceList.size(), resources.size());
IVersionSpecificBundleFactory bundleFactory = ctx.newBundleFactory();
bundleFactory.initializeBundleFromResourceList(null, subResourceList, null, null, 0, BundleTypeEnum.TRANSACTION);
IBaseResource subBundle = bundleFactory.getResourceBundle();
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(subBundle);
ourLog.info("Final bundle: {}", FileUtils.byteCountToDisplaySize(encoded.length()));
if (targetServer.startsWith("file://")) {
String path = targetServer.substring("file://".length());
ourLog.info("Writing bundle to: {}", path);
File file = new File(path);
if (file.exists()) {
throw new Exception("File already exists: " + file.getAbsolutePath());
}
FileWriter w = new FileWriter(file, false);
w.append(encoded);
w.close();
} else {
ourLog.info("Uploading bundle to server: " + targetServer);
IGenericClient fhirClient = newClient(ctx, targetServer);
fhirClient.registerInterceptor(new GZipContentInterceptor());
long start = System.currentTimeMillis();
try {
fhirClient.transaction().withBundle(encoded).execute();
} catch (BaseServerResponseException e) {
ourLog.error("Failed to upload bundle:HTTP " + e.getStatusCode() + ": " + e.getMessage());
ourLog.error("Failing bundle: {}", encoded);
}
long delay = System.currentTimeMillis() - start;
ourLog.info("Finished uploading bundle to server (took {} ms)", delay);
}
subResourceList.clear();
}
return bundle;
}

View File

@ -1,19 +1,18 @@
package ca.uhn.fhir.cli;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu3;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import parser.IgPackParserDstu3;
import parser.IgPackValidationSupportDstu3;
import java.io.File;
import java.io.FileInputStream;

View File

@ -4,7 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;

View File

@ -1,32 +1,87 @@
package ca.uhn.fhir.cli;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import org.apache.commons.cli.*;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.resource.StructureDefinition;
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.dstu2.resource.*;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class ValidationDataUploader extends BaseCommand {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationDataUploader.class);
private ArrayList<IIdType> myExcludes;
private void filterBundle(ca.uhn.fhir.model.dstu2.resource.Bundle theBundle) {
for (Iterator<Entry> iter = theBundle.getEntry().iterator(); iter.hasNext(); ) {
IBaseResource next = iter.next().getResource();
for (IIdType nextExclude : myExcludes) {
if (nextExclude.hasResourceType() && nextExclude.toUnqualifiedVersionless().getValue().equals(next.getIdElement().toUnqualifiedVersionless().getValue())) {
iter.remove();
continue;
} else if (nextExclude.getIdPart().equals(next.getIdElement().getIdPart())) {
iter.remove();
continue;
}
}
}
}
private void filterBundle(org.hl7.fhir.dstu3.model.Bundle theBundle) {
for (Iterator<BundleEntryComponent> iter = theBundle.getEntry().iterator(); iter.hasNext(); ) {
IBaseResource next = iter.next().getResource();
for (IIdType nextExclude : myExcludes) {
if (nextExclude.hasResourceType() && nextExclude.toUnqualifiedVersionless().getValue().equals(next.getIdElement().toUnqualifiedVersionless().getValue())) {
iter.remove();
continue;
} else if (nextExclude.getIdPart().equals(next.getIdElement().getIdPart())) {
iter.remove();
continue;
}
}
}
}
private void filterBundle(org.hl7.fhir.r4.model.Bundle theBundle) {
for (Iterator<org.hl7.fhir.r4.model.Bundle.BundleEntryComponent> iter = theBundle.getEntry().iterator(); iter.hasNext(); ) {
IBaseResource next = iter.next().getResource();
for (IIdType nextExclude : myExcludes) {
if (nextExclude.hasResourceType() && nextExclude.toUnqualifiedVersionless().getValue().equals(next.getIdElement().toUnqualifiedVersionless().getValue())) {
iter.remove();
continue;
} else if (nextExclude.getIdPart().equals(next.getIdElement().getIdPart())) {
iter.remove();
continue;
}
}
}
}
@Override
public String getCommandDescription() {
return "Uploads the conformance resources (StructureDefinition and ValueSet) from the official FHIR definitions.";
@ -43,11 +98,15 @@ public class ValidationDataUploader extends BaseCommand {
Option opt;
addFhirVersionOption(options);
opt = new Option("t", "target", true, "Base URL for the target server (e.g. \"http://example.com/fhir\")");
opt.setRequired(true);
options.addOption(opt);
opt = new Option("e", "exclude", true, "Exclude uploading the given resources, e.g. \"-e dicom-dcim,foo\"");
opt.setRequired(false);
options.addOption(opt);
return options;
}
@ -63,11 +122,24 @@ public class ValidationDataUploader extends BaseCommand {
FhirContext ctx = getSpecVersionContext(theCommandLine);
if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU2) {
uploadDefinitionsDstu2(targetServer, ctx);
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3){
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.DSTU3) {
uploadDefinitionsDstu3(targetServer, ctx);
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.R4){
} else if (ctx.getVersion().getVersion() == FhirVersionEnum.R4) {
uploadDefinitionsR4(targetServer, ctx);
}
String exclude = theCommandLine.getOptionValue("e");
myExcludes = new ArrayList<>();
if (isNotBlank(exclude)) {
for (String next : exclude.split(",")) {
if (isNotBlank(next)) {
IIdType id = ctx.getVersion().newIdType();
id.setValue(next);
myExcludes.add(id);
}
}
}
}
private void uploadDefinitionsDstu2(String targetServer, FhirContext ctx) throws CommandFailureException {
@ -79,7 +151,7 @@ public class ValidationDataUploader extends BaseCommand {
String vsContents;
try {
ctx.getVersion().getPathToSchemaDefinitions();
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/"+"valuesets.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/" + "valuesets.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
@ -91,14 +163,14 @@ public class ValidationDataUploader extends BaseCommand {
ValueSet next = (ValueSet) i.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading ValueSet {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/"+"v3-codesystems.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/" + "v3-codesystems.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
@ -110,14 +182,14 @@ public class ValidationDataUploader extends BaseCommand {
ValueSet next = (ValueSet) i.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading v3-codesystems ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading v3-codesystems ValueSet {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/"+"v2-tables.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/" + "v2-tables.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
@ -128,7 +200,7 @@ public class ValidationDataUploader extends BaseCommand {
ValueSet next = (ValueSet) i.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
@ -138,7 +210,7 @@ public class ValidationDataUploader extends BaseCommand {
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] mappingLocations;
try {
mappingLocations = patternResolver.getResources("classpath*:org/hl7/fhir/instance/model/profile/"+"*.profile.xml");
mappingLocations = patternResolver.getResources("classpath*:org/hl7/fhir/instance/model/profile/" + "*.profile.xml");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
@ -153,7 +225,7 @@ public class ValidationDataUploader extends BaseCommand {
}
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading StructureDefinition {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading StructureDefinition {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
try {
client.update().resource(next).execute();
} catch (Exception e) {
@ -178,14 +250,15 @@ public class ValidationDataUploader extends BaseCommand {
int count = 0;
org.hl7.fhir.dstu3.model.Bundle bundle;
String vsContents;
try {
ctx.getVersion().getPathToSchemaDefinitions();
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/"+"valuesets.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/" + "valuesets.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
@ -194,8 +267,8 @@ public class ValidationDataUploader extends BaseCommand {
next.setId(next.getIdElement().toUnqualifiedVersionless());
int bytes = ctx.newXmlParser().encodeResourceToString(next).length();
ourLog.info("Uploading ValueSet {}/{} : {} ({} bytes}", new Object[] { count, total, next.getIdElement().getValue(), bytes });
ourLog.info("Uploading ValueSet {}/{} : {} ({} bytes}", new Object[]{count, total, next.getIdElement().getValue(), bytes});
try {
IIdType id = client.update().resource(next).execute().getId();
ourLog.info(" - Got ID: {}", id.getValue());
@ -206,47 +279,50 @@ public class ValidationDataUploader extends BaseCommand {
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/"+"v3-codesystems.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/" + "v3-codesystems.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
for (BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading v3-codesystems ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading v3-codesystems ValueSet {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/"+"v2-tables.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/valueset/" + "v2-tables.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
for (BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
if (next.getIdElement().isIdPartValidLong()) {
next.setIdElement(new IdType("v2-"+ next.getIdElement().getIdPart()));
next.setIdElement(new IdType("v2-" + next.getIdElement().getIdPart()));
}
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
ourLog.info("Finished uploading ValueSets");
uploadDstu3Profiles(ctx, client, "profiles-resources");
uploadDstu3Profiles(ctx, client, "profiles-types");
uploadDstu3Profiles(ctx, client, "profiles-others");
@ -270,11 +346,12 @@ public class ValidationDataUploader extends BaseCommand {
try {
theCtx.getVersion().getPathToSchemaDefinitions();
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/valueset/"+"valuesets.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/valueset/" + "valuesets.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
bundle = theCtx.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
@ -284,7 +361,7 @@ public class ValidationDataUploader extends BaseCommand {
int bytes = theCtx.newXmlParser().encodeResourceToString(next).length();
ourLog.info("Uploading ValueSet {}/{} : {} ({} bytes}", new Object[] { count, total, next.getIdElement().getValue(), bytes });
ourLog.info("Uploading ValueSet {}/{} : {} ({} bytes}", new Object[]{count, total, next.getIdElement().getValue(), bytes});
try {
IIdType id = client.update().resource(next).execute().getId();
ourLog.info(" - Got ID: {}", id.getValue());
@ -295,40 +372,42 @@ public class ValidationDataUploader extends BaseCommand {
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/valueset/"+"v3-codesystems.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/valueset/" + "v3-codesystems.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
bundle = theCtx.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
for (org.hl7.fhir.r4.model.Bundle.BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.r4.model.Resource next = i.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading v3-codesystems ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading v3-codesystems ValueSet {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/valueset/"+"v2-tables.xml"), "UTF-8");
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/valueset/" + "v2-tables.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
bundle = theCtx.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
for (org.hl7.fhir.r4.model.Bundle.BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.r4.model.Resource next = i.getResource();
if (next.getIdElement().isIdPartValidLong()) {
next.setIdElement(new org.hl7.fhir.r4.model.IdType("v2-"+ next.getIdElement().getIdPart()));
next.setIdElement(new org.hl7.fhir.r4.model.IdType("v2-" + next.getIdElement().getIdPart()));
}
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[]{count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
@ -360,9 +439,10 @@ public class ValidationDataUploader extends BaseCommand {
}
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
Collections.sort(bundle.getEntry(), new Comparator<BundleEntryComponent>() {
@Override
public int compare(BundleEntryComponent theO1, BundleEntryComponent theO2) {
@ -377,18 +457,19 @@ public class ValidationDataUploader extends BaseCommand {
}
// StructureDefinition, then OperationDefinition, then CompartmentDefinition
return theO2.getResource().getClass().getName().compareTo(theO1.getResource().getClass().getName());
}});
}
});
for (BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
if (next instanceof CapabilityStatement) {
continue;
}
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] { name, count, total, next.getIdElement().getValue() });
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[]{name, count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;
}
}
@ -406,6 +487,7 @@ public class ValidationDataUploader extends BaseCommand {
}
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents);
filterBundle(bundle);
total = bundle.getEntry().size();
count = 1;
@ -423,7 +505,8 @@ public class ValidationDataUploader extends BaseCommand {
}
// StructureDefinition, then OperationDefinition, then CompartmentDefinition
return theO2.getResource().getClass().getName().compareTo(theO1.getResource().getClass().getName());
}});
}
});
for (org.hl7.fhir.r4.model.Bundle.BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.r4.model.Resource next = i.getResource();
@ -432,7 +515,7 @@ public class ValidationDataUploader extends BaseCommand {
continue;
}
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] { name, count, total, next.getIdElement().getValue() });
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[]{name, count, total, next.getIdElement().getValue()});
client.update().resource(next).execute();
count++;

View File

@ -1,4 +1,4 @@
package parser;
package ca.uhn.fhir.igpacks.parser;
import ca.uhn.fhir.context.FhirContext;
@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.util.StopWatch;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.ImplementationGuide;
import org.hl7.fhir.instance.model.api.IBaseResource;

View File

@ -1,7 +1,7 @@
package parser;
package ca.uhn.fhir.igpacks.parser;
import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.StructureDefinition;

View File

@ -2,13 +2,12 @@ package ca.uhn.fhir.igpack.parser;
import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu3;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import parser.IgPackParserDstu3;
import static org.junit.Assert.*;

View File

@ -1,7 +1,7 @@
package ca.uhn.fhir.jpa.config.dstu3;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.utils.IResourceValidator.BestPracticeWarningLevel;
/*

View File

@ -24,7 +24,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.*;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;

View File

@ -27,8 +27,8 @@ import java.util.Collections;
import java.util.List;
import org.apache.commons.codec.binary.StringUtils;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus;
import org.hl7.fhir.dstu3.model.ValueSet.*;

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
/*
* #%L

View File

@ -31,7 +31,7 @@ import javax.measure.unit.Unit;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestSecurityComponent;
import org.hl7.fhir.dstu3.model.Enumeration;
@ -55,7 +55,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamExtractorDstu3.class);
@Autowired
private org.hl7.fhir.dstu3.hapi.validation.IValidationSupport myValidationSupport;
private org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport myValidationSupport;
/**
* Constructor
@ -690,7 +690,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
*/
@Override
protected List<Object> extractValues(String thePaths, IBaseResource theResource) {
IWorkerContext worker = new org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext(getContext(), myValidationSupport);
IWorkerContext worker = new org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext(getContext(), myValidationSupport);
FHIRPathEngine fp = new FHIRPathEngine(worker);
List<Object> values = new ArrayList<Object>();
@ -736,7 +736,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
}
@VisibleForTesting
void setValidationSupportForTesting(org.hl7.fhir.dstu3.hapi.validation.IValidationSupport theValidationSupport) {
void setValidationSupportForTesting(org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport theValidationSupport) {
myValidationSupport = theValidationSupport;
}

View File

@ -1,5 +1,40 @@
package ca.uhn.fhir.jpa.term;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.util.StopWatch;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.CoverageIgnore;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.lucene.search.Query;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.dstu3.model.ValueSet.*;
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -12,9 +47,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* 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.
@ -22,36 +57,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* limitations under the License.
* #L%
*/
import java.util.*;
import org.apache.lucene.search.Query;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.dstu3.model.ValueSet.*;
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.util.StopWatch;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.util.CoverageIgnore;
import ca.uhn.fhir.util.UrlUtil;
public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements IValidationSupport, IHapiTerminologySvcDstu3 {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HapiTerminologySvcDstu3.class);

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.jpa.term;
* #L%
*/
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
public interface IHapiTerminologySvcDstu3 extends IHapiTerminologySvc, IValidationSupport {
// nothing

View File

@ -12,7 +12,7 @@ import javax.persistence.EntityManager;
import org.apache.commons.io.IOUtils;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.*;

View File

@ -5,7 +5,7 @@ import static org.junit.Assert.fail;
import javax.persistence.EntityManager;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;

View File

@ -9,7 +9,7 @@ import java.util.Set;
import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.Observation;
import org.junit.AfterClass;
import org.junit.BeforeClass;

View File

@ -20,24 +20,25 @@ package org.hl7.fhir.dstu3.hapi.ctx;
* #L%
*/
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.hapi.fluentpath.FluentPathDstu3;
import org.hl7.fhir.dstu3.hapi.rest.server.Dstu3BundleFactory;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.support.IContextValidationSupport;
import ca.uhn.fhir.fluentpath.IFluentPath;
import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory;
import ca.uhn.fhir.util.ReflectionUtil;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.hapi.fluentpath.FluentPathDstu3;
import org.hl7.fhir.dstu3.hapi.rest.server.Dstu3BundleFactory;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.*;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class FhirDstu3 implements IFhirVersion {
@ -50,7 +51,12 @@ public class FhirDstu3 implements IFhirVersion {
@Override
public IContextValidationSupport<?, ?, ?, ?, ?, ?> createValidationSupport() {
return new DefaultProfileValidationSupport();
String className = "org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport";
try {
return (IContextValidationSupport<?, ?, ?, ?, ?, ?>) Class.forName(className).newInstance();
} catch (Exception theE) {
throw new ConfigurationException(className + " is not on classpath. Make sure that hapi-fhir-validation-VERSION.jar is available.");
}
}
@Override

View File

@ -1,34 +1,15 @@
package org.hl7.fhir.dstu3.hapi.validation;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
package org.hl7.fhir.dstu3.hapi.ctx;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.CoverageIgnore;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.formats.IParser;
import org.hl7.fhir.dstu3.formats.ParserType;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.ExpansionProfile;
import org.hl7.fhir.dstu3.model.MetadataResource;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.dstu3.model.ResourceType;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptReferenceComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
@ -42,10 +23,10 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.CoverageIgnore;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander, ValueSetExpanderFactory {
private final FhirContext myCtx;
@ -196,7 +177,7 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
@Override
public ValidationResult validateCode(String theSystem, String theCode, String theDisplay) {
CodeValidationResult result = myValidationSupport.validateCode(myCtx, theSystem, theCode, theDisplay);
IValidationSupport.CodeValidationResult result = myValidationSupport.validateCode(myCtx, theSystem, theCode, theDisplay);
if (result == null) {
return null;
}
@ -359,4 +340,4 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
throw new UnsupportedOperationException();
}
}
}

View File

@ -1,4 +1,4 @@
package org.hl7.fhir.dstu3.hapi.validation;
package org.hl7.fhir.dstu3.hapi.ctx;
import java.util.List;

View File

@ -1,17 +1,16 @@
package org.hl7.fhir.dstu3.hapi.fluentpath;
import java.util.List;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.fluentpath.FluentPathExecutionException;
import ca.uhn.fhir.fluentpath.IFluentPath;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.Base;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBase;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.fluentpath.FluentPathExecutionException;
import ca.uhn.fhir.fluentpath.IFluentPath;
import java.util.List;
public class FluentPathDstu3 implements IFluentPath {

View File

@ -11,9 +11,8 @@ import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.Resource;
@ -30,15 +29,6 @@ public class GraphQLProviderDstu3 {
private Logger ourLog = LoggerFactory.getLogger(GraphQLProviderDstu3.class);
private IGraphQLStorageServices<Resource, Reference, Bundle> myStorageServices;
/**
* Constructor which uses a default context and validation support object
*
* @param theStorageServices The storage services (this object will be used to retrieve various resources as required by the GraphQL engine)
*/
public GraphQLProviderDstu3(IGraphQLStorageServices<Resource, Reference, Bundle> theStorageServices) {
this(FhirContext.forDstu3(), new DefaultProfileValidationSupport(), theStorageServices);
}
/**
* Constructor which uses the given worker context
*

View File

@ -309,8 +309,10 @@ public class GraphQLEngine {
}
if (fp.length() == 0)
for (Base v : values) {
if (passesExtensionMode(v, extensionMode))
result.add(v);
if (v != null) {
if (passesExtensionMode(v, extensionMode))
result.add(v);
}
} else {
FHIRPathEngine fpe = new FHIRPathEngine(this.context);
ExpressionNode node = fpe.parse(fp.toString().substring(5));
@ -416,6 +418,8 @@ public class GraphQLEngine {
if (prop == null) {
if ((sel.getField().getName().equals("resourceType") && source instanceof Resource))
target.addField("resourceType", false).addValue(new StringValue(source.fhirType()));
else if ((sel.getField().getName().equals("id") && source instanceof Resource))
target.addField("id", false).addValue(new StringValue(((Resource) source).getIdElement().getIdPart()));
else if ((sel.getField().getName().equals("resource") && source.fhirType().equals("Reference")))
processReference(context, source, sel.getField(), target);
else if (isResourceName(sel.getField().getName(), "List") && (source instanceof Resource))

View File

@ -1,446 +0,0 @@
package org.hl7.fhir.dstu3.validation;
/*
Copyright (c) 2011+, HL7, Inc
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
import java.text.MessageFormat;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
public class BaseValidator {
protected Source source;
/**
* Test a rule and add a {@link IssueSeverity#FATAL} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean fail(List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, line, col, path, msg, IssueSeverity.FATAL));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#FATAL} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean fail(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String msg) {
if (!thePass) {
String path = toPath(pathParts);
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.FATAL));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#FATAL} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean fail(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
if (!thePass) {
String path = toPath(pathParts);
errors.add(new ValidationMessage(source, type, -1, -1, path, formatMessage(theMessage, theMessageArguments), IssueSeverity.FATAL));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#FATAL} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean fail(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.FATAL));
}
return thePass;
}
private String formatMessage(String theMessage, Object... theMessageArguments) {
String message;
if (theMessageArguments != null && theMessageArguments.length > 0) {
message = MessageFormat.format(theMessage, theMessageArguments);
} else {
message = theMessage;
}
return message;
}
protected boolean grammarWord(String w) {
return w.equals("and") || w.equals("or") || w.equals("a") || w.equals("the") || w.equals("for") || w.equals("this") || w.equals("that") || w.equals("of");
}
/**
* Test a rule and add a {@link IssueSeverity#INFORMATION} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean hint(List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, line, col, path, msg, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#INFORMATION} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean hint(List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) {
if (!thePass) {
String message = formatMessage(theMessage, theMessageArguments);
errors.add(new ValidationMessage(source, type, line, col, path, message, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#INFORMATION} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean hint(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
if (!thePass) {
String path = toPath(pathParts);
String message = formatMessage(theMessage, theMessageArguments);
errors.add(new ValidationMessage(source, type, -1, -1, path, message, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#INFORMATION} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean hint(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#ERROR} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean rule(List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) {
if (!thePass) {
String message = formatMessage(theMessage, theMessageArguments);
errors.add(new ValidationMessage(source, type, line, col, path, message, IssueSeverity.ERROR));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#ERROR} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean rule(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String msg) {
if (!thePass) {
String path = toPath(pathParts);
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.ERROR));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#ERROR} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean rule(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
if (!thePass) {
String path = toPath(pathParts);
String message = formatMessage(theMessage, theMessageArguments);
errors.add(new ValidationMessage(source, type, -1, -1, path, message, IssueSeverity.ERROR));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#ERROR} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean rule(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.ERROR));
}
return thePass;
}
static public boolean rule(List<ValidationMessage> errors, Source source, IssueType type, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.ERROR));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#ERROR} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean rule(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg, String html) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, html, IssueSeverity.ERROR));
}
return thePass;
}
protected String splitByCamelCase(String s) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isUpperCase(c) && !(i == 0 || Character.isUpperCase(s.charAt(i-1))))
b.append(' ');
b.append(c);
}
return b.toString();
}
protected String stripPunctuation(String s, boolean numbers) {
StringBuilder b = new StringBuilder();
for (char c : s.toCharArray()) {
int t = Character.getType(c);
if (t == Character.UPPERCASE_LETTER || t == Character.LOWERCASE_LETTER || t == Character.TITLECASE_LETTER || t == Character.MODIFIER_LETTER || t == Character.OTHER_LETTER || (t == Character.DECIMAL_DIGIT_NUMBER && numbers) || (t == Character.LETTER_NUMBER && numbers) || c == ' ')
b.append(c);
}
return b.toString();
}
private String toPath(List<String> pathParts) {
if (pathParts == null || pathParts.isEmpty()) {
return "";
}
return "//" + StringUtils.join(pathParts, '/');
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean warning(List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) {
if (!thePass) {
msg = formatMessage(msg, theMessageArguments);
errors.add(new ValidationMessage(source, type, line, col, path, msg, IssueSeverity.WARNING));
}
return thePass;
}
protected boolean warningOrError(boolean isError, List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) {
if (!thePass) {
msg = formatMessage(msg, theMessageArguments);
errors.add(new ValidationMessage(source, type, line, col, path, msg, isError ? IssueSeverity.ERROR : IssueSeverity.WARNING));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean warning(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
if (!thePass) {
String path = toPath(pathParts);
String message = formatMessage(theMessage, theMessageArguments);
errors.add(new ValidationMessage(source, type, -1, -1, path, message, IssueSeverity.WARNING));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean warning(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.WARNING));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean warning(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg, String html) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, html, IssueSeverity.WARNING));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean warning(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg, String html, Object... theMessageArguments) {
if (!thePass) {
msg = formatMessage(msg, theMessageArguments);
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, html, IssueSeverity.WARNING));
}
return thePass;
}
//---------
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean suppressedwarning(List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) {
if (!thePass) {
msg = formatMessage(msg, theMessageArguments);
errors.add(new ValidationMessage(source, type, line, col, path, msg, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean suppressedwarning(List<ValidationMessage> errors, IssueType type, List<String> pathParts, boolean thePass, String theMessage, Object... theMessageArguments) {
if (!thePass) {
String path = toPath(pathParts);
String message = formatMessage(theMessage, theMessageArguments);
errors.add(new ValidationMessage(source, type, -1, -1, path, message, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean suppressedwarning(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean suppressedwarning(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg, String html) {
if (!thePass) {
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, html, IssueSeverity.INFORMATION));
}
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean suppressedwarning(List<ValidationMessage> errors, IssueType type, String path, boolean thePass, String msg, String html, Object... theMessageArguments) {
if (!thePass) {
msg = formatMessage(msg, theMessageArguments);
errors.add(new ValidationMessage(source, type, -1, -1, path, msg, html, IssueSeverity.INFORMATION));
}
return thePass;
}
}

View File

@ -1,23 +0,0 @@
package org.hl7.fhir.dstu3.validation;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine;
/**
* Placeholder class - Do not use
*/
class ValidationEngine {
private ValidationEngine() {
}
public IWorkerContext getContext() {
return null;
}
public FHIRPathEngine getFpe() {
return null;
}
}

View File

@ -1,66 +0,0 @@
package org.hl7.fhir.dstu3.validation;
/*
Copyright (c) 2011+, HL7, Inc
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
import java.util.List;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class ValidationErrorHandler implements ErrorHandler {
private List<ValidationMessage> outputs;
private String path;
public ValidationErrorHandler(List<ValidationMessage> outputs, String path) {
this.outputs = outputs;
this.path = path;
}
@Override
public void error(SAXParseException arg0) throws SAXException {
outputs.add(new ValidationMessage(Source.Schema, IssueType.INVALID, arg0.getLineNumber(), arg0.getColumnNumber(), path, arg0.getMessage(), IssueSeverity.ERROR));
}
@Override
public void fatalError(SAXParseException arg0) throws SAXException {
outputs.add(new ValidationMessage(Source.Schema, IssueType.INVALID, arg0.getLineNumber(), arg0.getColumnNumber(), path, arg0.getMessage(), IssueSeverity.FATAL));
}
@Override
public void warning(SAXParseException arg0) throws SAXException {
outputs.add(new ValidationMessage(Source.Schema, IssueType.INVALID, arg0.getLineNumber(), arg0.getColumnNumber(), path, arg0.getMessage(), IssueSeverity.WARNING));
}
}

View File

@ -1,59 +1,5 @@
package ca.uhn.fhir.parser;
import static org.apache.commons.lang3.StringUtils.countMatches;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import org.apache.commons.io.IOUtils;
import org.hamcrest.Matchers;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Address.AddressUse;
import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.CapabilityStatement.UnknownContentCode;
import org.hl7.fhir.dstu3.model.Condition.ConditionVerificationStatus;
import org.hl7.fhir.dstu3.model.Enumeration;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import com.google.common.base.Charsets;
import com.google.common.collect.Sets;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.parser.IParserErrorHandler.IParseLocation;
@ -62,8 +8,47 @@ import ca.uhn.fhir.parser.XmlParserDstu3Test.TestPatientFor327;
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.*;
import net.sf.json.*;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
import com.google.common.base.Charsets;
import com.google.common.collect.Sets;
import net.sf.json.JSON;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;
import org.apache.commons.io.IOUtils;
import org.hamcrest.Matchers;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.dstu3.model.Address.AddressUse;
import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.CapabilityStatement.UnknownContentCode;
import org.hl7.fhir.dstu3.model.Condition.ConditionVerificationStatus;
import org.hl7.fhir.dstu3.model.Enumeration;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse;
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.countMatches;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.*;
public class JsonParserDstu3Test {
private static FhirContext ourCtx = FhirContext.forDstu3();
@ -74,77 +59,6 @@ public class JsonParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
@Test
public void testActivityDefinitionElementsOrder() throws Exception {
final String origContent = "{\"resourceType\":\"ActivityDefinition\",\"id\":\"x1\",\"url\":\"http://testing.org\",\"status\":\"draft\",\"timingDateTime\":\"2011-02-03\"}";
final IParser parser = ourCtx.newJsonParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ActivityDefinition fhirObj = parser.parseResource(ActivityDefinition.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
@Test
public void testConceptMapElementsOrder() throws Exception {
final String origContent = "{\"resourceType\":\"ConceptMap\",\"id\":\"x1\",\"url\":\"http://testing.org\",\"status\":\"draft\",\"sourceUri\":\"http://y1\"}";
final IParser parser = ourCtx.newJsonParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ConceptMap fhirObj = parser.parseResource(ConceptMap.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
/**
* See #563

View File

@ -32,8 +32,6 @@ import org.apache.commons.lang.StringUtils;
import org.hamcrest.collection.IsEmptyCollection;
import org.hamcrest.core.StringContains;
import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Address.AddressUse;
import org.hl7.fhir.dstu3.model.Address.AddressUseEnumFactory;
@ -142,80 +140,6 @@ public class XmlParserDstu3Test {
}
/**
* See #683
*/
@Test
public void testChildOrderWithChoiceType() throws Exception {
final String origContent = "<ActivityDefinition xmlns=\"http://hl7.org/fhir\"><id value=\"x1\"/><url value=\"http://testing.org\"/><status value=\"draft\"/><timingDateTime value=\"2011-02-03\"/></ActivityDefinition>";
final IParser parser = ourCtx.newXmlParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ActivityDefinition fhirObj = parser.parseResource(ActivityDefinition.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
@Test
public void testConceptMapElementsOrder() throws Exception {
final String origContent = "<ConceptMap xmlns=\"http://hl7.org/fhir\"><id value=\"x1\"/><url value=\"http://testing.org\"/><status value=\"draft\"/><sourceUri value=\"http://url1\"/></ConceptMap>";
final IParser parser = ourCtx.newXmlParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ConceptMap fhirObj = parser.parseResource(ConceptMap.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
@Test
public void testContainedResourceInExtensionUndeclared() {

View File

@ -173,6 +173,10 @@
<artifactId>phloc-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
<reporting>

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;

View File

@ -7,6 +7,8 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine.IEvaluationContext;
import org.hl7.fhir.dstu3.utils.IResourceValidator.BestPracticeWarningLevel;

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.dstu3.hapi.validation;
import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.MetadataResource;
import org.hl7.fhir.dstu3.model.StructureDefinition;

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.dstu3.hapi.validation;
import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;

View File

@ -1,18 +1,17 @@
package ca.uhn.fhir.fluentpath;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*;
import java.util.List;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.dstu3.model.HumanName;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.StringType;
import org.junit.AfterClass;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import java.util.List;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*;
public class FluentPathTest {

View File

@ -9,6 +9,7 @@ import ca.uhn.fhir.rest.param.TokenAndListParam;
import ca.uhn.fhir.util.PortUtil;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil;
import jdk.nashorn.internal.ir.annotations.Ignore;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
@ -18,6 +19,8 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hamcrest.Matchers;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -32,7 +35,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@ -55,6 +57,8 @@ public class GraphQLDstu3ProviderTest {
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
ServletHandler proxyHandler = new ServletHandler();
RestfulServer servlet = new RestfulServer(ourCtx);
servlet.setDefaultResponseEncoding(EncodingEnum.JSON);
@ -62,7 +66,7 @@ public class GraphQLDstu3ProviderTest {
servlet.registerProvider(new DummyPatientResourceProvider());
MyStorageServices storageServices = new MyStorageServices();
servlet.registerProvider(new GraphQLProviderDstu3(storageServices));
servlet.registerProvider(new GraphQLProviderDstu3(ourCtx, new DefaultProfileValidationSupport(), storageServices));
ServletHolder servletHolder = new ServletHolder(servlet);
proxyHandler.addServletWithMapping(servletHolder, "/*");
ourServer.setHandler(proxyHandler);
@ -93,13 +97,13 @@ public class GraphQLDstu3ProviderTest {
assertEquals("{\n" +
" \"name\":[{\n" +
" \"family\":\"FAMILY\",\n" +
" \"family\":[\"FAMILY\"],\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" +
" },{\n" +
" \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" +
" }]\n" +
"}", responseContent);
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), Matchers.startsWith("application/json"));
} finally {
IOUtils.closeQuietly(status.getEntity().getContent());
@ -122,13 +126,13 @@ public class GraphQLDstu3ProviderTest {
" \"Patient\":{\n" +
" \"name\":[{\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"],\n" +
" \"family\":\"FAMILY\"\n" +
" \"family\":[\"FAMILY\"]\n" +
" },{\n" +
" \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" +
" }]\n" +
" }\n" +
"}", responseContent);
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), Matchers.startsWith("application/json"));
} finally {
IOUtils.closeQuietly(status.getEntity().getContent());
@ -150,7 +154,7 @@ public class GraphQLDstu3ProviderTest {
assertEquals("{\n" +
" \"PatientList\":[{\n" +
" \"name\":[{\n" +
" \"family\":\"pet\",\n" +
" \"family\":[\"pet\"],\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" +
" },{\n" +
" \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" +
@ -161,7 +165,7 @@ public class GraphQLDstu3ProviderTest {
" }]\n" +
" }]\n" +
"}", responseContent);
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), Matchers.startsWith("application/json"));
} finally {
IOUtils.closeQuietly(status.getEntity().getContent());
@ -183,10 +187,10 @@ public class GraphQLDstu3ProviderTest {
assertEquals("{\n" +
" \"name\":[{\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"],\n" +
" \"family\":\"FAMILY\"\n" +
" \"family\":[\"FAMILY\"]\n" +
" }]\n" +
"}", responseContent);
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), Matchers.startsWith("application/json"));
} finally {
IOUtils.closeQuietly(status.getEntity().getContent());

View File

@ -1,6 +1,5 @@
package ca.uhn.fhir.rest.server;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@ -21,6 +20,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hamcrest.Matchers;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.IdType;
@ -95,8 +95,8 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Request-Validation"));
assertThat(responseContent, not(containsString("<severity value=\"error\"/>")));
assertThat(status.toString(), Matchers.containsString("X-FHIR-Request-Validation"));
assertThat(responseContent, Matchers.not(Matchers.containsString("<severity value=\"error\"/>")));
}
@Test
@ -121,8 +121,8 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(422, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Request-Validation"));
assertThat(responseContent, containsString("\"severity\":\"error\""));
assertThat(status.toString(), Matchers.containsString("X-FHIR-Request-Validation"));
assertThat(responseContent, Matchers.containsString("\"severity\":\"error\""));
}
@Test
@ -144,7 +144,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation")));
assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Request-Validation")));
}
@Test
@ -169,7 +169,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(status.toString(), (containsString("X-FHIR-Request-Validation: NO ISSUES")));
assertThat(status.toString(), (Matchers.containsString("X-FHIR-Request-Validation: NO ISSUES")));
}
@Test
@ -197,7 +197,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(422, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Request-Validation"));
assertThat(status.toString(), Matchers.containsString("X-FHIR-Request-Validation"));
}
@Test
@ -222,7 +222,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(422, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Request-Validation"));
assertThat(status.toString(), Matchers.containsString("X-FHIR-Request-Validation"));
}
@Test
@ -249,7 +249,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Request-Validation: {\"resourceType\":\"OperationOutcome"));
assertThat(status.toString(), Matchers.containsString("X-FHIR-Request-Validation: {\"resourceType\":\"OperationOutcome"));
}
@ -280,7 +280,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(500, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("<diagnostics value=\"java.lang.NullPointerException\"/>"));
assertThat(responseContent, Matchers.containsString("<diagnostics value=\"java.lang.NullPointerException\"/>"));
}
@SuppressWarnings("unchecked")
@ -310,7 +310,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation")));
assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Request-Validation")));
}
@SuppressWarnings("unchecked")
@ -340,7 +340,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(500, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("<diagnostics value=\"FOO\"/>"));
assertThat(responseContent, Matchers.containsString("<diagnostics value=\"FOO\"/>"));
}
@SuppressWarnings("unchecked")
@ -370,7 +370,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation")));
assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Request-Validation")));
}
@Test
@ -392,7 +392,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(201, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation")));
assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Request-Validation")));
}
/**
@ -410,7 +410,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
assertEquals(204, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation")));
assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Request-Validation")));
} finally {
IOUtils.closeQuietly(status);
}
@ -434,7 +434,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("CapabilityStatement"));
assertThat(responseContent, Matchers.containsString("CapabilityStatement"));
}
@Test
@ -450,7 +450,7 @@ public class RequestValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Request-Validation")));
assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Request-Validation")));
assertEquals(true, ourLastRequestWasSearch);
}

View File

@ -1,9 +1,6 @@
package ca.uhn.fhir.rest.server;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
@ -16,26 +13,19 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hamcrest.Matchers;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.*;
import org.mockito.Mockito;
import ca.uhn.fhir.context.FhirContext;
@ -107,8 +97,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(500, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("<diagnostics value=\"java.lang.NullPointerException\"/>"));
Assert.assertEquals(500, status.getStatusLine().getStatusCode());
Assert.assertThat(responseContent, Matchers.containsString("<diagnostics value=\"java.lang.NullPointerException\"/>"));
}
@SuppressWarnings("unchecked")
@ -137,8 +127,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation")));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Response-Validation")));
}
@SuppressWarnings("unchecked")
@ -167,8 +157,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(500, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("<diagnostics value=\"FOO\"/>"));
Assert.assertEquals(500, status.getStatusLine().getStatusCode());
Assert.assertThat(responseContent, Matchers.containsString("<diagnostics value=\"FOO\"/>"));
}
@SuppressWarnings("unchecked")
@ -197,8 +187,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation")));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Response-Validation")));
}
@ -216,8 +206,8 @@ public class ResponseValidatingInterceptorDstu3Test {
try {
ourLog.info("Response was:\n{}", status);
assertEquals(204, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation")));
Assert.assertEquals(204, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Response-Validation")));
} finally {
IOUtils.closeQuietly(status);
}
@ -249,9 +239,9 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), endsWith("..."));
assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), startsWith("{\"resourceType\":\"OperationOutcome\""));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), Matchers.endsWith("..."));
Assert.assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), Matchers.startsWith("{\"resourceType\":\"OperationOutcome\""));
}
{
myInterceptor.setMaximumHeaderLength(100);
@ -263,9 +253,9 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), endsWith("..."));
assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), startsWith("{\"resourceType\":\"OperationOutcome\""));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), Matchers.endsWith("..."));
Assert.assertThat(status.getFirstHeader("X-FHIR-Response-Validation").getValue(), Matchers.startsWith("{\"resourceType\":\"OperationOutcome\""));
}
}
@ -287,8 +277,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), (containsString(
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), (Matchers.containsString(
"X-FHIR-Response-Validation: {\"resourceType\":\"OperationOutcome\",\"issue\":[{\"severity\":\"information\",\"code\":\"informational\",\"diagnostics\":\"No issues detected\"}]}")));
}
@ -314,9 +304,9 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(422, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Response-Validation"));
assertThat(responseContent, containsString("<severity value=\"error\"/>"));
Assert.assertEquals(422, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.containsString("X-FHIR-Response-Validation"));
Assert.assertThat(responseContent, Matchers.containsString("<severity value=\"error\"/>"));
}
@Test
@ -336,8 +326,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation")));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Response-Validation")));
}
@Test
@ -360,8 +350,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), (containsString("X-FHIR-Response-Validation: NO ISSUES")));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), (Matchers.containsString("X-FHIR-Response-Validation: NO ISSUES")));
}
@Test
@ -386,8 +376,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(422, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Response-Validation"));
Assert.assertEquals(422, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.containsString("X-FHIR-Response-Validation"));
}
/**
@ -412,8 +402,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(422, status.getStatusLine().getStatusCode());
assertThat(status.toString(), containsString("X-FHIR-Response-Validation"));
Assert.assertEquals(422, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.containsString("X-FHIR-Response-Validation"));
}
@Test
@ -433,8 +423,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.trace("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation")));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Response-Validation")));
}
@Test
@ -453,8 +443,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), not(containsString("X-FHIR-Response-Validation")));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), Matchers.not(Matchers.containsString("X-FHIR-Response-Validation")));
}
@Test
@ -474,8 +464,8 @@ public class ResponseValidatingInterceptorDstu3Test {
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(status.toString(), (containsString("X-FHIR-Response-Validation")));
Assert.assertEquals(200, status.getStatusLine().getStatusCode());
Assert.assertThat(status.toString(), (Matchers.containsString("X-FHIR-Response-Validation")));
}
@AfterClass

View File

@ -0,0 +1,174 @@
package ca.uhn.fhir.validation;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.ActivityDefinition;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ParserWithValidationDstu3Test {
private static final Logger ourLog = LoggerFactory.getLogger(ParserWithValidationDstu3Test.class);
private static FhirContext ourCtx = FhirContext.forDstu3();
@Test
public void testActivityDefinitionElementsOrder() throws Exception {
final String origContent = "{\"resourceType\":\"ActivityDefinition\",\"id\":\"x1\",\"url\":\"http://testing.org\",\"status\":\"draft\",\"timingDateTime\":\"2011-02-03\"}";
final IParser parser = ourCtx.newJsonParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ActivityDefinition fhirObj = parser.parseResource(ActivityDefinition.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
/**
* See #683
*/
@Test
public void testChildOrderWithChoiceTypeXml() throws Exception {
final String origContent = "<ActivityDefinition xmlns=\"http://hl7.org/fhir\"><id value=\"x1\"/><url value=\"http://testing.org\"/><status value=\"draft\"/><timingDateTime value=\"2011-02-03\"/></ActivityDefinition>";
final IParser parser = ourCtx.newXmlParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ActivityDefinition fhirObj = parser.parseResource(ActivityDefinition.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
@Test
public void testConceptMapElementsOrder() throws Exception {
final String origContent = "{\"resourceType\":\"ConceptMap\",\"id\":\"x1\",\"url\":\"http://testing.org\",\"status\":\"draft\",\"sourceUri\":\"http://y1\"}";
final IParser parser = ourCtx.newJsonParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ConceptMap fhirObj = parser.parseResource(ConceptMap.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
@Test
public void testConceptMapElementsOrderXml() throws Exception {
final String origContent = "<ConceptMap xmlns=\"http://hl7.org/fhir\"><id value=\"x1\"/><url value=\"http://testing.org\"/><status value=\"draft\"/><sourceUri value=\"http://url1\"/></ConceptMap>";
final IParser parser = ourCtx.newXmlParser();
DefaultProfileValidationSupport validationSupport = new DefaultProfileValidationSupport();
// verify that InstanceValidator likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, origContent);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
ConceptMap fhirObj = parser.parseResource(ConceptMap.class, origContent);
String content = parser.encodeResourceToString(fhirObj);
ourLog.info("Serialized form: {}", content);
// verify that InstanceValidator still likes the format
{
IValidationContext<IBaseResource> validationCtx = ValidationContext.forText(ourCtx, content);
new FhirInstanceValidator(validationSupport).validateResource(validationCtx);
ValidationResult result = validationCtx.toResult();
for (SingleValidationMessage msg : result.getMessages()) {
ourLog.info("{}", msg);
}
Assert.assertEquals(0, result.getMessages().size());
}
// verify that the original and newly serialized match
Assert.assertEquals(origContent, content);
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -16,9 +16,9 @@ import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;

View File

@ -3,8 +3,8 @@ package org.hl7.fhir.dstu3.elementmodel;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.model.ElementDefinition;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.exceptions.DefinitionException;
@ -15,13 +15,12 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.*;
/**
* Created by axemj on 14/07/2017.
*/
public class PropertyTest {
public class PropertyDstu3Test {
private static final FhirContext ourCtx = FhirContext.forDstu3();
private Property property;

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.dstu3.hapi.validation;
import static org.junit.Assert.*;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.junit.AfterClass;
import org.junit.Test;

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.validation;
package org.hl7.fhir.dstu3.hapi.validation;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
@ -23,14 +23,15 @@ import java.util.Set;
import java.util.TreeSet;
import java.util.zip.GZIPInputStream;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhir.validation.SingleValidationMessage;
import ca.uhn.fhir.validation.ValidationResult;
import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.model.Base;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.Bundle;

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.validation;
package org.hl7.fhir.dstu3.hapi.validation;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
@ -12,14 +12,14 @@ import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.SingleValidationMessage;
import ca.uhn.fhir.validation.ValidationResult;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport.CodeValidationResult;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;

View File

@ -1,19 +1,14 @@
package org.hl7.fhir.dstu3.hapi.validation;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.*;
import ca.uhn.fhir.validation.schematron.SchematronBaseValidator;
import org.apache.commons.io.IOUtils;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.dstu3.model.*;
@ -25,23 +20,35 @@ import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.parser.XmlParserDstu3Test;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.*;
import ca.uhn.fhir.validation.schematron.SchematronBaseValidator;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class ResourceValidatorDstu3Test {
private static FhirContext ourCtx = FhirContext.forDstu3();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidatorDstu3Test.class);
private static FhirContext ourCtx = FhirContext.forDstu3();
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
private List<SingleValidationMessage> logResultsAndReturnNonInformationalOnes(ValidationResult theOutput) {
List<SingleValidationMessage> retVal = new ArrayList<SingleValidationMessage>();
int index = 0;
for (SingleValidationMessage next : theOutput.getMessages()) {
ourLog.info("Result {}: {} - {} - {}",
new Object[]{index, next.getSeverity(), next.getLocationString(), next.getMessage()});
index++;
if (next.getSeverity() != ResultSeverityEnum.INFORMATION) {
retVal.add(next);
}
}
return retVal;
}
/**
@ -75,24 +82,24 @@ public class ResourceValidatorDstu3Test {
assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Invalid attribute value \"2000-15-31\": Invalid date/time format: \"2000-15-31\"", e.getMessage());
}
}
@Test
@Ignore
public void testValidateCareTeamProfile() {
CareTeam careTeam = new CareTeam();
careTeam
.addParticipant()
.setMember(new Reference("Practitioner/1647bbb2-3b12-43cc-923c-a475f817e881"))
.setOnBehalfOf(new Reference("Organization/5859a28f-01e7-42d8-a8ba-48b31679a828"));
.setMember(new Reference("Practitioner/1647bbb2-3b12-43cc-923c-a475f817e881"))
.setOnBehalfOf(new Reference("Organization/5859a28f-01e7-42d8-a8ba-48b31679a828"));
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
String encoded = parser.encodeResourceToString(careTeam);
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(encoded);
String resultString = parser.setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
ourLog.info(resultString);
@ -101,45 +108,29 @@ public class ResourceValidatorDstu3Test {
assertThat(resultString, StringContains.containsString("cvc-pattern-valid"));
}
@Test
public void testValidateCareTeamXsd() {
CareTeam careTeam = new CareTeam();
careTeam
.addParticipant()
.setMember(new Reference("http://example.com/Practitioner/1647bbb2-3b12-43cc-923c-a475f817e881"))
.setOnBehalfOf(new Reference("Organization/5859a28f-01e7-42d8-a8ba-48b31679a828"));
.setMember(new Reference("http://example.com/Practitioner/1647bbb2-3b12-43cc-923c-a475f817e881"))
.setOnBehalfOf(new Reference("Organization/5859a28f-01e7-42d8-a8ba-48b31679a828"));
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
String encoded = parser.encodeResourceToString(careTeam);
ourLog.info(encoded);
FhirValidator val = ourCtx.newValidator();
ValidationResult result = val.validateWithResult(encoded);
String resultString = parser.setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
ourLog.info(resultString);
assertThat(resultString, containsString("No issues detected during validation"));
}
@Test
public void testValidateCodeableConceptContainingOnlyGoodCode() {
Patient p = new Patient();
p.getMaritalStatus().addCoding().setSystem("http://hl7.org/fhir/v3/MaritalStatus").setCode("M");
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult output = val.validateWithResult(p);
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(output);
assertEquals(0, all.size());
assertEquals(0, output.getMessages().size());
}
@Test
@ -159,24 +150,136 @@ public class ResourceValidatorDstu3Test {
assertEquals(ResultSeverityEnum.WARNING, output.getMessages().get(0).getSeverity());
}
@Test
public void testValidateCodeableConceptContainingOnlyGoodCode() {
Patient p = new Patient();
p.getMaritalStatus().addCoding().setSystem("http://hl7.org/fhir/v3/MaritalStatus").setCode("M");
private List<SingleValidationMessage> logResultsAndReturnNonInformationalOnes(ValidationResult theOutput) {
List<SingleValidationMessage> retVal = new ArrayList<SingleValidationMessage>();
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
val.registerValidatorModule(new FhirInstanceValidator());
int index = 0;
for (SingleValidationMessage next : theOutput.getMessages()) {
ourLog.info("Result {}: {} - {} - {}",
new Object[] { index, next.getSeverity(), next.getLocationString(), next.getMessage() });
index++;
ValidationResult output = val.validateWithResult(p);
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(output);
assertEquals(0, all.size());
assertEquals(0, output.getMessages().size());
}
if (next.getSeverity() != ResultSeverityEnum.INFORMATION) {
retVal.add(next);
}
}
@Test
@Ignore
public void testValidateDifferentPropertyButSameStartsWithPath() throws Exception {
return retVal;
}
EligibilityResponse fhirObj = new EligibilityResponse();
BenefitComponent benComp = fhirObj.addInsurance().addBenefitBalance().addFinancial();
// Test between .benefit[x] and benefitUsed[x]
// benComp.setBenefitUsed(new UnsignedIntType(2));
String input = ourCtx.newXmlParser().encodeResourceToString(fhirObj);
FhirValidator validator = ourCtx.newValidator();
validator.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = validator.validateWithResult(input);
// we should get some results, not an exception
assertEquals(4, result.getMessages().size());
}
@Test
public void testValidateJsonNumericId() {
String input = "{\"resourceType\": \"Patient\",\n" +
" \"id\": 123,\n" +
" \"meta\": {\n" +
" \"versionId\": \"29\",\n" +
" \"lastUpdated\": \"2015-12-22T19:53:11.000Z\"\n" +
" },\n" +
" \"communication\": {\n" +
" \"language\": {\n" +
" \"coding\": [\n" +
" {\n" +
" \"system\": \"urn:ietf:bcp:47\",\n" +
" \"code\": \"hi\",\n" +
" \"display\": \"Hindi\",\n" +
" \"userSelected\": false\n" +
" }],\n" +
" \"text\": \"Hindi\"\n" +
" },\n" +
" \"preferred\": true\n" +
" }\n" +
"}";
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult output = val.validateWithResult(input);
OperationOutcome operationOutcome = (OperationOutcome) output.toOperationOutcome();
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(encoded);
assertThat(encoded, containsString("Error parsing JSON: the primitive value must be a string"));
}
/**
* Per email from Jon Zammit
*/
@Test
@Ignore
public void testValidateQuestionnaire() throws IOException {
String input = IOUtils.toString(getClass().getResourceAsStream("/questionnaire_jon_z_20160506.xml"), StandardCharsets.UTF_8);
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(input);
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
String ooencoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(ooencoded);
assertTrue(result.isSuccessful());
}
/**
* TODO: re-enable this
*/
@Test
@Ignore
public void testValidateQuestionnaireWithCanonicalUrl() {
String input = "{\n" +
" \"resourceType\": \"Questionnaire\",\n" +
" \"url\": \"http://some.example.url\",\n" +
" \"status\": \"published\",\n" +
" \"subjectType\": [\n" +
" \"Patient\"\n" +
" ],\n" +
" \"item\": [\n" +
" {\n" +
" \"linkId\": \"example-question\",\n" +
" \"text\": \"Is the sky blue?\",\n" +
" \"type\": \"choice\",\n" +
" \"options\": {\n" +
" \"reference\": \"http://loinc.org/vs/LL3044-6\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
Questionnaire q = new Questionnaire();
q = ourCtx.newJsonParser().parseResource(Questionnaire.class, input);
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(q);
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(encoded);
}
/**
* Make sure that the elements that appear in all resources (meta, language, extension, etc) all appear in the correct order
@ -184,7 +287,7 @@ public class ResourceValidatorDstu3Test {
@Test
public void testValidateResourceWithResourceElements() {
XmlParserDstu3Test.TestPatientFor327 patient = new XmlParserDstu3Test.TestPatientFor327();
TestPatientFor327 patient = new TestPatientFor327();
patient.setBirthDate(new Date());
patient.setId("123");
patient.getText().setDivAsString("<div>FOO</div>");
@ -223,6 +326,55 @@ public class ResourceValidatorDstu3Test {
assertThat(ooencoded, containsString("Unknown extension http://foo"));
}
/**
* See https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium= email&utm_source=footer
*/
@Test
public void testValidateWithExtensionsJson() {
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
myPatient.setId("1");
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setSystem("furry-white")));
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
myPatient.addName().setFamily("FamilyName");
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
String messageString = p.encodeResourceToString(myPatient);
ourLog.info(messageString);
//@formatter:off
assertThat(messageString, stringContainsInOrder(
"meta",
"String Extension",
"Organization/2.25.79433498044103547197447759549862032393",
"furry-grey",
"furry-white",
"FamilyName"
));
assertThat(messageString, not(stringContainsInOrder(
"extension",
"meta"
)));
//@formatter:on
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(messageString);
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(encoded);
assertTrue(result.isSuccessful());
assertThat(messageString, containsString("valueReference"));
assertThat(messageString, not(containsString("valueResource")));
}
/**
* See https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium= email&utm_source=footer
*/
@ -274,168 +426,27 @@ public class ResourceValidatorDstu3Test {
assertThat(messageString, not(containsString("valueResource")));
}
/**
* Per email from Jon Zammit
*/
@Test
@Ignore
public void testValidateQuestionnaire() throws IOException {
String input = IOUtils.toString(getClass().getResourceAsStream("/questionnaire_jon_z_20160506.xml"), StandardCharsets.UTF_8);
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(input);
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
String ooencoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(ooencoded);
assertTrue(result.isSuccessful());
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
@Test
public void testValidateJsonNumericId() {
String input = "{\"resourceType\": \"Patient\",\n" +
" \"id\": 123,\n" +
" \"meta\": {\n" +
" \"versionId\": \"29\",\n" +
" \"lastUpdated\": \"2015-12-22T19:53:11.000Z\"\n" +
" },\n" +
" \"communication\": {\n" +
" \"language\": {\n" +
" \"coding\": [\n" +
" {\n" +
" \"system\": \"urn:ietf:bcp:47\",\n" +
" \"code\": \"hi\",\n" +
" \"display\": \"Hindi\",\n" +
" \"userSelected\": false\n" +
" }],\n" +
" \"text\": \"Hindi\"\n" +
" },\n" +
" \"preferred\": true\n" +
" }\n" +
"}";
@ResourceDef(name = "Patient")
public static class TestPatientFor327 extends Patient {
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult output = val.validateWithResult(input);
private static final long serialVersionUID = 1L;
OperationOutcome operationOutcome = (OperationOutcome) output.toOperationOutcome();
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(encoded);
@Child(name = "testCondition")
@ca.uhn.fhir.model.api.annotation.Extension(url = "testCondition", definedLocally = true, isModifier = false)
private List<Reference> testConditions = null;
assertThat(encoded, containsString("Error parsing JSON: the primitive value must be a string"));
public List<Reference> getConditions() {
return this.testConditions;
}
}
/**
* See https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium= email&utm_source=footer
*/
@Test
public void testValidateWithExtensionsJson() {
PatientProfileDstu3 myPatient = new PatientProfileDstu3();
myPatient.setId("1");
myPatient.setColorPrimary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setCode("furry-grey")));
myPatient.setColorSecondary(new CodeableConcept().addCoding(new Coding().setSystem("http://example.com#animalColor").setSystem("furry-white")));
myPatient.setOwningOrganization(new Reference("Organization/2.25.79433498044103547197447759549862032393"));
myPatient.addName().setFamily("FamilyName");
myPatient.addExtension().setUrl("http://foo.com/example").setValue(new StringType("String Extension"));
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
String messageString = p.encodeResourceToString(myPatient);
ourLog.info(messageString);
//@formatter:off
assertThat(messageString, stringContainsInOrder(
"meta",
"String Extension",
"Organization/2.25.79433498044103547197447759549862032393",
"furry-grey",
"furry-white",
"FamilyName"
));
assertThat(messageString, not(stringContainsInOrder(
"extension",
"meta"
)));
//@formatter:on
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(messageString);
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(encoded);
assertTrue(result.isSuccessful());
assertThat(messageString, containsString("valueReference"));
assertThat(messageString, not(containsString("valueResource")));
}
@Test
@Ignore
public void testValidateDifferentPropertyButSameStartsWithPath() throws Exception {
EligibilityResponse fhirObj = new EligibilityResponse();
BenefitComponent benComp = fhirObj.addInsurance().addBenefitBalance().addFinancial();
// Test between .benefit[x] and benefitUsed[x]
// benComp.setBenefitUsed(new UnsignedIntType(2));
String input = ourCtx.newXmlParser().encodeResourceToString(fhirObj);
FhirValidator validator = ourCtx.newValidator();
validator.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = validator.validateWithResult(input);
// we should get some results, not an exception
assertEquals(4, result.getMessages().size());
}
/**
* TODO: re-enable this
*/
@Test
@Ignore
public void testValidateQuestionnaireWithCanonicalUrl() {
String input = "{\n" +
" \"resourceType\": \"Questionnaire\",\n" +
" \"url\": \"http://some.example.url\",\n" +
" \"status\": \"published\",\n" +
" \"subjectType\": [\n" +
" \"Patient\"\n" +
" ],\n" +
" \"item\": [\n" +
" {\n" +
" \"linkId\": \"example-question\",\n" +
" \"text\": \"Is the sky blue?\",\n" +
" \"type\": \"choice\",\n" +
" \"options\": {\n" +
" \"reference\": \"http://loinc.org/vs/LL3044-6\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
Questionnaire q = new Questionnaire();
q = ourCtx.newJsonParser().parseResource(Questionnaire.class, input);
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
val.registerValidatorModule(new FhirInstanceValidator());
ValidationResult result = val.validateWithResult(q);
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
ourLog.info(encoded);
public void setCondition(List<Reference> ref) {
this.testConditions = ref;
}
}
}

View File

@ -1,9 +1,11 @@
package ca.uhn.fhir.validation;
package org.hl7.fhir.dstu3.hapi.validation;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
import org.junit.AfterClass;
import org.junit.Test;

View File

@ -1,322 +1,323 @@
package org.hl7.fhir.dstu3.hapi.validation;
import static org.junit.Assert.assertEquals;
import java.util.*;
import javax.annotation.Nullable;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.utils.StructureMapUtilities;
import org.junit.Before;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
public class StructureMapTest {
/**
* The logger object.
*/
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StructureMapTest.class);
/**
* The basic fhir context used to parse structure definitions.
*/
FhirContext context;
/**
* HapiFhirContext used when building strucutre map utilities.
*/
IWorkerContext hapiContext;
/**
* path to the files used to test the profile generator.
*/
String resourcePath = null;
/**
* Used to validate definitions as well as add new structure definitions to a registry.
*/
PrePopulatedValidationSupport validationSupport;
public StructureMap.StructureMapGroupRuleSourceComponent buildSource(String context, @Nullable String element, @Nullable String variable, @Nullable String type, @Nullable Integer min,
@Nullable String max) {
StructureMap.StructureMapGroupRuleSourceComponent retVal = new StructureMap.StructureMapGroupRuleSourceComponent();
retVal.setContext(context);
if (element != null)
retVal.setElement(element);
if (variable != null)
retVal.setVariable(variable);
if (type != null)
retVal.setType(type);
if (min != null)
retVal.setMin(min);
if (max != null)
retVal.setMax(max);
return retVal;
}
public List<StructureMap.StructureMapGroupRuleSourceComponent> buildSourceList(StructureMap.StructureMapGroupRuleSourceComponent[] sources) {
List<StructureMap.StructureMapGroupRuleSourceComponent> retVal = new ArrayList<StructureMap.StructureMapGroupRuleSourceComponent>();
retVal.addAll(Arrays.asList(sources));
return retVal;
}
public StructureMap.StructureMapGroupRuleTargetComponent buildTarget(@Nullable String context, @Nullable String element, @Nullable String variable,
@Nullable StructureMap.StructureMapTransform transform, @Nullable TargetParam[] params) throws Exception {
StructureMap.StructureMapGroupRuleTargetComponent retVal = new StructureMap.StructureMapGroupRuleTargetComponent();
if (context != null)
retVal.setContext(context);
if (element != null)
retVal.setElement(element);
if (variable != null)
retVal.setVariable(variable);
if (transform != null)
retVal.setTransform(transform);
if (params != null) {
if (params.length > 0)
retVal.setParameter(this.constructParameters(params));
}
return retVal;
}
public List<StructureMap.StructureMapGroupRuleTargetComponent> buildTargetList(StructureMap.StructureMapGroupRuleTargetComponent[] sources) {
List<StructureMap.StructureMapGroupRuleTargetComponent> retVal = new ArrayList<StructureMap.StructureMapGroupRuleTargetComponent>();
retVal.addAll(Arrays.asList(sources));
return retVal;
}
public List<StructureMap.StructureMapGroupComponent> buildTestGroup() throws Exception {
List<StructureMap.StructureMapGroupComponent> retVal = new ArrayList<StructureMap.StructureMapGroupComponent>();
StructureMap.StructureMapGroupComponent group = new StructureMap.StructureMapGroupComponent();
group.setName("TestStructureToCoding");
group.setTypeMode(StructureMap.StructureMapGroupTypeMode.TYPEANDTYPES);
group.setInput(this.buildTestInput());
group.setRule(this.buildTestRules());
retVal.add(group);
return retVal;
}
public List<StructureMap.StructureMapGroupInputComponent> buildTestInput() {
List<StructureMap.StructureMapGroupInputComponent> retVal = new ArrayList<StructureMap.StructureMapGroupInputComponent>();
StructureMap.StructureMapGroupInputComponent sourceIn = new StructureMap.StructureMapGroupInputComponent();
StructureMap.StructureMapGroupInputComponent targetIn = new StructureMap.StructureMapGroupInputComponent();
sourceIn.setName("source");
sourceIn.setType("TestStructure");
sourceIn.setMode(StructureMap.StructureMapInputMode.SOURCE);
targetIn.setName("target");
targetIn.setType("http://hl7.org/fhir/StructureDefinition/Coding");
targetIn.setMode(StructureMap.StructureMapInputMode.TARGET);
retVal.add(sourceIn);
retVal.add(targetIn);
return retVal;
}
public List<StructureMap.StructureMapGroupRuleComponent> buildTestRules() throws Exception {
List<StructureMap.StructureMapGroupRuleComponent> retVal = new ArrayList<StructureMap.StructureMapGroupRuleComponent>();
StructureMap.StructureMapGroupRuleComponent codingSystem = new StructureMap.StructureMapGroupRuleComponent();
StructureMap.StructureMapGroupRuleComponent codingExtension = new StructureMap.StructureMapGroupRuleComponent();
codingSystem.setName("Coding.System");
codingSystem.setSource(this.buildSourceList(new StructureMap.StructureMapGroupRuleSourceComponent[] {
this.buildSource("source", "system", "v", null, null, null)
}));
codingSystem.setTarget(this.buildTargetList(new StructureMap.StructureMapGroupRuleTargetComponent[] {
this.buildTarget("target", "system", null, StructureMap.StructureMapTransform.COPY, new TargetParam[] { new TargetParam("Id", "v") })
}));
codingExtension.setName("Coding.Extension");
codingExtension.setSource(this.buildSourceList(new StructureMap.StructureMapGroupRuleSourceComponent[] {
this.buildSource("source", "system", "v", null, null, null)
}));
codingExtension.setTarget(this.buildTargetList(new StructureMap.StructureMapGroupRuleTargetComponent[] {
this.buildTarget("target", "extension", "ex", null, new TargetParam[] { new TargetParam("", "") }),
this.buildTarget("ex", "url", null, StructureMap.StructureMapTransform.COPY, new TargetParam[] { new TargetParam("Id", "v") }),
this.buildTarget("ex", "value", null, StructureMap.StructureMapTransform.COPY, new TargetParam[] { new TargetParam("String", "v") })
}));
retVal.add(codingSystem);
retVal.add(codingExtension);
return retVal;
}
public List<StructureMap.StructureMapGroupRuleTargetParameterComponent> constructParameters(TargetParam[] params) throws Exception {
List<StructureMap.StructureMapGroupRuleTargetParameterComponent> parameterComponents = new ArrayList<StructureMap.StructureMapGroupRuleTargetParameterComponent>();
for (TargetParam tp : params) {
if (tp.getType() == "Id") // TODO: Convert TypeParam.Type into an Enum.
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new IdType().setValue(tp.getValue())));
else if (tp.getType() == "String")
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue((new StringType().setValue(tp.getValue()))));
else if (tp.getType() == "Boolean") {
boolean bValue = Boolean.getBoolean(tp.getValue());
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new BooleanType().setValue(bValue)));
} else if (tp.getType() == "Integer") {
int iValue = Integer.getInteger(tp.getValue());
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new IntegerType().setValue(iValue)));
} else if (tp.getType() == "Decimal") {
long lValue = Long.getLong(tp.getValue());
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new DecimalType(lValue)));
}
}
return parameterComponents;
}
public List<StructureMap.StructureMapStructureComponent> createMapStructureList() {
List<StructureMap.StructureMapStructureComponent> retVal = new ArrayList<StructureMap.StructureMapStructureComponent>();
StructureMap.StructureMapStructureComponent source = new StructureMap.StructureMapStructureComponent();
StructureMap.StructureMapStructureComponent target = new StructureMap.StructureMapStructureComponent();
source.setUrl("http://opencimi.org/structuredefinition/TestStructure");
source.setMode(StructureMap.StructureMapModelMode.SOURCE);
target.setUrl("http://hl7.org/fhir/StructureDefinition/Coding");
target.setMode(StructureMap.StructureMapModelMode.TARGET);
retVal.add(source);
retVal.add(target);
return retVal;
}
public StructureDefinition.StructureDefinitionDifferentialComponent createTestDiff() {
StructureDefinition.StructureDefinitionDifferentialComponent retVal = new StructureDefinition.StructureDefinitionDifferentialComponent();
List<ElementDefinition> eList = new ArrayList<ElementDefinition>();
ElementDefinition ed0 = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed0.setId("TestStructure");
ed0.setSliceName("TestStructure");
ed0.setPath("TestStructure");
// ed0.setBase(base);
ed0.setMin(1);
ed0.setMax("1");
eList.add(ed0);
ElementDefinition ed = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed.setId("system");
ed.setSliceName("system");
ed.setPath("TestStructure.system");
// ed.setBase(base);
ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging"));
// ed.setType(this.createTypeRefList());
eList.add(ed);
retVal.setElement(eList);
return retVal;
}
public StructureDefinition.StructureDefinitionSnapshotComponent createTestSnapshot() {
StructureDefinition.StructureDefinitionSnapshotComponent retVal = new StructureDefinition.StructureDefinitionSnapshotComponent();
List<ElementDefinition> eList = new ArrayList<ElementDefinition>();
ElementDefinition ed0 = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed0.setId("TestStructure");
ed0.setSliceName("TestStructure");
ed0.setPath("TestStructure");
// ed0.setBase(base);
ed0.setMin(1);
ed0.setMax("1");
eList.add(ed0);
ElementDefinition ed = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed.setId("system");
ed.setSliceName("system");
ed.setPath("TestStructure.system");
// ed.setBase(base);
ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging"));
// ed.setType(this.createTypeRefList());
ed.setMin(1);
ed.setMax("1");
eList.add(ed);
retVal.setElement(eList);
return retVal;
}
public StructureDefinition createTestStructure() {
StructureDefinition sd = new StructureDefinition();
sd.setId("TestStructure");
sd.setUrl("http://opencimi.org/structuredefinition/TestStructure");
sd.setStatus(Enumerations.PublicationStatus.DRAFT);
sd.setName("TestStructure");
sd.setType("TestStructure");
sd.setSnapshot(this.createTestSnapshot());
sd.setDifferential(this.createTestDiff());
sd.setKind(StructureDefinition.StructureDefinitionKind.LOGICAL);
return sd;
}
public StructureMap createTestStructuremap() throws Exception {
StructureMap retMap = new StructureMap();
retMap.setUrl("http://opencimi.org/structuremap/testtransform");
retMap.setName("TestTransform");
retMap.setStatus(Enumerations.PublicationStatus.DRAFT);
retMap.setStructure(this.createMapStructureList());
retMap.setGroup(this.buildTestGroup());
return retMap;
}
/**
* Sets up the resource paths as well as create the contexts using a defalut validator to start with.
*
* @throws Exception
*/
@Before
public void setUp() throws Exception {
if (this.context == null) {
this.context = FhirContext.forDstu3();
}
}
/**
* See #682
*/
@Test
public void testMappingTransform() throws Exception {
Map<String, StructureMap> maps = new HashMap<String, StructureMap>(); // Instantiate a hashmap for StructureMaps
this.validationSupport = new PrePopulatedValidationSupport(); // Create Validation Instance
for (StructureDefinition sd : new DefaultProfileValidationSupport().fetchAllStructureDefinitions(this.context)) { // Read in the default Structure Definitions into a validator that allows custom
// declared structure definitions.
this.validationSupport.addStructureDefinition(sd);
}
StructureDefinition sd1 = this.createTestStructure(); // Calls a method that constructs a comp
this.validationSupport.addStructureDefinition(sd1); // Add custom structure to validation support.
this.hapiContext = new HapiWorkerContext(this.context, this.validationSupport);// Init the Hapi Work
StructureMap map = this.createTestStructuremap();
maps.put(map.getUrl(), map);
StructureMapUtilities scu = new StructureMapUtilities(hapiContext, maps, null, null);
List<StructureDefinition> result = scu.analyse(null, map).getProfiles();
assertEquals(1, result.size());
ourLog.info(context.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.get(0)));
}
public class TargetParam {
private String type;
private String value;
public TargetParam(String type, String value) {
this.type = type;
this.value = value;
}
public String getType() {
return type;
}
public String getValue() {
return value;
}
public void setType(String type) {
this.type = type;
}
public void setValue(String value) {
this.value = value;
}
}
}
package org.hl7.fhir.dstu3.hapi.validation;
import static org.junit.Assert.assertEquals;
import java.util.*;
import javax.annotation.Nullable;
import org.hl7.fhir.dstu3.context.IWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.utils.StructureMapUtilities;
import org.junit.Before;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
public class StructureMapTest {
/**
* The logger object.
*/
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(StructureMapTest.class);
/**
* The basic fhir context used to parse structure definitions.
*/
FhirContext context;
/**
* HapiFhirContext used when building strucutre map utilities.
*/
IWorkerContext hapiContext;
/**
* path to the files used to test the profile generator.
*/
String resourcePath = null;
/**
* Used to validate definitions as well as add new structure definitions to a registry.
*/
PrePopulatedValidationSupport validationSupport;
public StructureMap.StructureMapGroupRuleSourceComponent buildSource(String context, @Nullable String element, @Nullable String variable, @Nullable String type, @Nullable Integer min,
@Nullable String max) {
StructureMap.StructureMapGroupRuleSourceComponent retVal = new StructureMap.StructureMapGroupRuleSourceComponent();
retVal.setContext(context);
if (element != null)
retVal.setElement(element);
if (variable != null)
retVal.setVariable(variable);
if (type != null)
retVal.setType(type);
if (min != null)
retVal.setMin(min);
if (max != null)
retVal.setMax(max);
return retVal;
}
public List<StructureMap.StructureMapGroupRuleSourceComponent> buildSourceList(StructureMap.StructureMapGroupRuleSourceComponent[] sources) {
List<StructureMap.StructureMapGroupRuleSourceComponent> retVal = new ArrayList<StructureMap.StructureMapGroupRuleSourceComponent>();
retVal.addAll(Arrays.asList(sources));
return retVal;
}
public StructureMap.StructureMapGroupRuleTargetComponent buildTarget(@Nullable String context, @Nullable String element, @Nullable String variable,
@Nullable StructureMap.StructureMapTransform transform, @Nullable TargetParam[] params) throws Exception {
StructureMap.StructureMapGroupRuleTargetComponent retVal = new StructureMap.StructureMapGroupRuleTargetComponent();
if (context != null)
retVal.setContext(context);
if (element != null)
retVal.setElement(element);
if (variable != null)
retVal.setVariable(variable);
if (transform != null)
retVal.setTransform(transform);
if (params != null) {
if (params.length > 0)
retVal.setParameter(this.constructParameters(params));
}
return retVal;
}
public List<StructureMap.StructureMapGroupRuleTargetComponent> buildTargetList(StructureMap.StructureMapGroupRuleTargetComponent[] sources) {
List<StructureMap.StructureMapGroupRuleTargetComponent> retVal = new ArrayList<StructureMap.StructureMapGroupRuleTargetComponent>();
retVal.addAll(Arrays.asList(sources));
return retVal;
}
public List<StructureMap.StructureMapGroupComponent> buildTestGroup() throws Exception {
List<StructureMap.StructureMapGroupComponent> retVal = new ArrayList<StructureMap.StructureMapGroupComponent>();
StructureMap.StructureMapGroupComponent group = new StructureMap.StructureMapGroupComponent();
group.setName("TestStructureToCoding");
group.setTypeMode(StructureMap.StructureMapGroupTypeMode.TYPEANDTYPES);
group.setInput(this.buildTestInput());
group.setRule(this.buildTestRules());
retVal.add(group);
return retVal;
}
public List<StructureMap.StructureMapGroupInputComponent> buildTestInput() {
List<StructureMap.StructureMapGroupInputComponent> retVal = new ArrayList<StructureMap.StructureMapGroupInputComponent>();
StructureMap.StructureMapGroupInputComponent sourceIn = new StructureMap.StructureMapGroupInputComponent();
StructureMap.StructureMapGroupInputComponent targetIn = new StructureMap.StructureMapGroupInputComponent();
sourceIn.setName("source");
sourceIn.setType("TestStructure");
sourceIn.setMode(StructureMap.StructureMapInputMode.SOURCE);
targetIn.setName("target");
targetIn.setType("http://hl7.org/fhir/StructureDefinition/Coding");
targetIn.setMode(StructureMap.StructureMapInputMode.TARGET);
retVal.add(sourceIn);
retVal.add(targetIn);
return retVal;
}
public List<StructureMap.StructureMapGroupRuleComponent> buildTestRules() throws Exception {
List<StructureMap.StructureMapGroupRuleComponent> retVal = new ArrayList<StructureMap.StructureMapGroupRuleComponent>();
StructureMap.StructureMapGroupRuleComponent codingSystem = new StructureMap.StructureMapGroupRuleComponent();
StructureMap.StructureMapGroupRuleComponent codingExtension = new StructureMap.StructureMapGroupRuleComponent();
codingSystem.setName("Coding.System");
codingSystem.setSource(this.buildSourceList(new StructureMap.StructureMapGroupRuleSourceComponent[] {
this.buildSource("source", "system", "v", null, null, null)
}));
codingSystem.setTarget(this.buildTargetList(new StructureMap.StructureMapGroupRuleTargetComponent[] {
this.buildTarget("target", "system", null, StructureMap.StructureMapTransform.COPY, new TargetParam[] { new TargetParam("Id", "v") })
}));
codingExtension.setName("Coding.Extension");
codingExtension.setSource(this.buildSourceList(new StructureMap.StructureMapGroupRuleSourceComponent[] {
this.buildSource("source", "system", "v", null, null, null)
}));
codingExtension.setTarget(this.buildTargetList(new StructureMap.StructureMapGroupRuleTargetComponent[] {
this.buildTarget("target", "extension", "ex", null, new TargetParam[] { new TargetParam("", "") }),
this.buildTarget("ex", "url", null, StructureMap.StructureMapTransform.COPY, new TargetParam[] { new TargetParam("Id", "v") }),
this.buildTarget("ex", "value", null, StructureMap.StructureMapTransform.COPY, new TargetParam[] { new TargetParam("String", "v") })
}));
retVal.add(codingSystem);
retVal.add(codingExtension);
return retVal;
}
public List<StructureMap.StructureMapGroupRuleTargetParameterComponent> constructParameters(TargetParam[] params) throws Exception {
List<StructureMap.StructureMapGroupRuleTargetParameterComponent> parameterComponents = new ArrayList<StructureMap.StructureMapGroupRuleTargetParameterComponent>();
for (TargetParam tp : params) {
if (tp.getType() == "Id") // TODO: Convert TypeParam.Type into an Enum.
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new IdType().setValue(tp.getValue())));
else if (tp.getType() == "String")
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue((new StringType().setValue(tp.getValue()))));
else if (tp.getType() == "Boolean") {
boolean bValue = Boolean.getBoolean(tp.getValue());
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new BooleanType().setValue(bValue)));
} else if (tp.getType() == "Integer") {
int iValue = Integer.getInteger(tp.getValue());
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new IntegerType().setValue(iValue)));
} else if (tp.getType() == "Decimal") {
long lValue = Long.getLong(tp.getValue());
parameterComponents.add(new StructureMap.StructureMapGroupRuleTargetParameterComponent().setValue(new DecimalType(lValue)));
}
}
return parameterComponents;
}
public List<StructureMap.StructureMapStructureComponent> createMapStructureList() {
List<StructureMap.StructureMapStructureComponent> retVal = new ArrayList<StructureMap.StructureMapStructureComponent>();
StructureMap.StructureMapStructureComponent source = new StructureMap.StructureMapStructureComponent();
StructureMap.StructureMapStructureComponent target = new StructureMap.StructureMapStructureComponent();
source.setUrl("http://opencimi.org/structuredefinition/TestStructure");
source.setMode(StructureMap.StructureMapModelMode.SOURCE);
target.setUrl("http://hl7.org/fhir/StructureDefinition/Coding");
target.setMode(StructureMap.StructureMapModelMode.TARGET);
retVal.add(source);
retVal.add(target);
return retVal;
}
public StructureDefinition.StructureDefinitionDifferentialComponent createTestDiff() {
StructureDefinition.StructureDefinitionDifferentialComponent retVal = new StructureDefinition.StructureDefinitionDifferentialComponent();
List<ElementDefinition> eList = new ArrayList<ElementDefinition>();
ElementDefinition ed0 = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed0.setId("TestStructure");
ed0.setSliceName("TestStructure");
ed0.setPath("TestStructure");
// ed0.setBase(base);
ed0.setMin(1);
ed0.setMax("1");
eList.add(ed0);
ElementDefinition ed = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed.setId("system");
ed.setSliceName("system");
ed.setPath("TestStructure.system");
// ed.setBase(base);
ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging"));
// ed.setType(this.createTypeRefList());
eList.add(ed);
retVal.setElement(eList);
return retVal;
}
public StructureDefinition.StructureDefinitionSnapshotComponent createTestSnapshot() {
StructureDefinition.StructureDefinitionSnapshotComponent retVal = new StructureDefinition.StructureDefinitionSnapshotComponent();
List<ElementDefinition> eList = new ArrayList<ElementDefinition>();
ElementDefinition ed0 = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed0.setId("TestStructure");
ed0.setSliceName("TestStructure");
ed0.setPath("TestStructure");
// ed0.setBase(base);
ed0.setMin(1);
ed0.setMax("1");
eList.add(ed0);
ElementDefinition ed = new ElementDefinition();
// ElementDefinition.ElementDefinitionBaseComponent base = new ElementDefinition.ElementDefinitionBaseComponent();
// base.setId("http://hl7.org/fhir/StructureDefinition/Element");
ed.setId("system");
ed.setSliceName("system");
ed.setPath("TestStructure.system");
// ed.setBase(base);
ed.setFixed(new UriType().setValue("HTTP://opencimi.org/structuredefinition/TestStructure.html#Debugging"));
// ed.setType(this.createTypeRefList());
ed.setMin(1);
ed.setMax("1");
eList.add(ed);
retVal.setElement(eList);
return retVal;
}
public StructureDefinition createTestStructure() {
StructureDefinition sd = new StructureDefinition();
sd.setId("TestStructure");
sd.setUrl("http://opencimi.org/structuredefinition/TestStructure");
sd.setStatus(Enumerations.PublicationStatus.DRAFT);
sd.setName("TestStructure");
sd.setType("TestStructure");
sd.setSnapshot(this.createTestSnapshot());
sd.setDifferential(this.createTestDiff());
sd.setKind(StructureDefinition.StructureDefinitionKind.LOGICAL);
return sd;
}
public StructureMap createTestStructuremap() throws Exception {
StructureMap retMap = new StructureMap();
retMap.setUrl("http://opencimi.org/structuremap/testtransform");
retMap.setName("TestTransform");
retMap.setStatus(Enumerations.PublicationStatus.DRAFT);
retMap.setStructure(this.createMapStructureList());
retMap.setGroup(this.buildTestGroup());
return retMap;
}
/**
* Sets up the resource paths as well as create the contexts using a defalut validator to start with.
*
* @throws Exception
*/
@Before
public void setUp() throws Exception {
if (this.context == null) {
this.context = FhirContext.forDstu3();
}
}
/**
* See #682
*/
@Test
public void testMappingTransform() throws Exception {
Map<String, StructureMap> maps = new HashMap<String, StructureMap>(); // Instantiate a hashmap for StructureMaps
this.validationSupport = new PrePopulatedValidationSupport(); // Create Validation Instance
for (StructureDefinition sd : new DefaultProfileValidationSupport().fetchAllStructureDefinitions(this.context)) { // Read in the default Structure Definitions into a validator that allows custom
// declared structure definitions.
this.validationSupport.addStructureDefinition(sd);
}
StructureDefinition sd1 = this.createTestStructure(); // Calls a method that constructs a comp
this.validationSupport.addStructureDefinition(sd1); // Add custom structure to validation support.
this.hapiContext = new HapiWorkerContext(this.context, this.validationSupport);// Init the Hapi Work
StructureMap map = this.createTestStructuremap();
maps.put(map.getUrl(), map);
StructureMapUtilities scu = new StructureMapUtilities(hapiContext, maps, null, null);
List<StructureDefinition> result = scu.analyse(null, map).getProfiles();
assertEquals(1, result.size());
ourLog.info(context.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.get(0)));
}
public class TargetParam {
private String type;
private String value;
public TargetParam(String type, String value) {
this.type = type;
this.value = value;
}
public String getType() {
return type;
}
public String getValue() {
return value;
}
public void setType(String type) {
this.type = type;
}
public void setValue(String value) {
this.value = value;
}
}
}

View File

@ -8,7 +8,7 @@ import java.util.List;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.model.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;

View File

@ -1,30 +0,0 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] - %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.eclipse" additivity="false" level="info">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org.apache" additivity="false" level="info">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org.thymeleaf" additivity="false" level="warn">
<appender-ref ref="STDOUT" />
</logger>
<!--
<logger name="ca.uhn.fhir.rest.client" additivity="false" level="trace">
<appender-ref ref="STDOUT" />
</logger>
-->
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,53 @@
{
"resourceType": "MedicationRequest",
"id": "196356",
"meta": {
"versionId": "2",
"lastUpdated": "2017-08-04T15:26:29.333-04:00",
"profile": [
]
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n <p>Viagra 100 mg Tablets</p>\n <p>\n <b>Creation Date: 2017-08-04</b>\n </p>\n </div>"
},
"status": "active",
"intent": "order",
"category": {
"coding": [
{
"system": "http://hl7.org/fhir/medication-request-category",
"code": "community"
}
]
},
"medicationCodeableConcept": {
"coding": [
{
"system": "http://www.nlm.nih.gov/research/umls/rxnorm",
"code": "316663",
"display": "Viagra"
}
]
},
"subject": {
"reference": "Patient/195975",
"display": "Mary Ann Mallady"
},
"authoredOn": "2017-08-03",
"requester": {
"agent": {
"reference": "Practitioner/196336"
}
},
"reasonCode": [
{
"coding": [
{
"system": "http://snomed.info/sct",
"code": "14760008"
}
]
}
]
}

View File

@ -0,0 +1,447 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="Patient"/>
<meta>
<lastUpdated value="2017-07-14T08:37:31.190+02:00"/>
</meta>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="1"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="2"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="3"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="4"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="5"/>
</ValueSet>
</contained>
<url value="http://www.myServer.com/fhir/StructureDefinition/Patient"/>
<version value="1.0"/>
<name value="Custom Patient"/>
<title value="Patient"/>
<status value="draft"/>
<experimental value="false"/>
<date value="2017-07-14T08:37:31+02:00"/>
<publisher value="Me"/>
<contact>
<name value="test"/>
<telecom>
<system value="email"/>
<value value="test@test.com"/>
<use value="work"/>
</telecom>
</contact>
<description value="Information about an individual receiving health care services"/>
<useContext>
<code>
<system value="urn:iso:std:iso:3166"/>
<code value="FR"/>
<display value="France"/>
</code>
</useContext>
<fhirVersion value="3.0.1"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Patient"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/patient"/>
<derivation value="constraint"/>
<snapshot>
<element>
<path value="Patient"/>
</element>
<element>
<path value="Patient.id"/>
<short value="Logical id of this artifact"/>
<definition value="The logical id of the resource, as used in the URL for the resource. Once assigned, this value never changes."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="id"/>
</type>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.meta"/>
<short value="Metadata about the resource"/>
<definition value="The metadata about the resource. This is content that is maintained by the infrastructure. Changes to the content may not always be associated with version changes to the resource."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Meta"/>
</type>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.text"/>
<max value="0"/>
</element>
<element>
<path value="Patient.contained"/>
<max value="0"/>
</element>
<element>
<path value="Patient.implicitRules"/>
<max value="0"/>
</element>
<element>
<path value="Patient.language"/>
<short value="Language of the resource content"/>
<definition value="The base language in which the resource is written."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="code"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<slicing>
<discriminator>
<type value="value"/>
<path value="url"/>
</discriminator>
<rules value="open"/>
</slicing>
<definition value="May be used to represent additional information that is not part of the basic definition of the element."/>
</element>
<element>
<path value="Patient.extension"/>
<short value="identityReliabilityCode"/>
<definition value="The patient identity reliability code"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/identityReliabilityCode"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/IDENTITYSTATUS"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="lunarBirthDate"/>
<definition value="The patient lunar's birth date"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/lunarBirthDate"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="legalStatus"/>
<definition value="The patient legal status"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/legalStatus"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/ADT_LEGALSTATUS"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="familyStatus"/>
<definition value="The patient family status"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/familyStatus"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/FAMILYSTATUS"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="birthPlace"/>
<definition value="The patient birth place"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://hl7.org/fhir/StructureDefinition/birthPlace"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="homeless"/>
<definition value="The patient being homeless, true if homeless"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/homeless"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="phoneConsent"/>
<definition value="The patient consent on phone level"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/phoneConsent"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/ADT_CONTACT_CONSENT_MOBILE"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="emailConsent"/>
<definition value="The patient consent on email level"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/emailConsent"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/ADT_CONTACT_CONSENT_EMAIL"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="comments"/>
<definition value="The patient comments"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/comments"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="nationality"/>
<definition value="The patient nationality"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://hl7.org/fhir/StructureDefinition/patient-nationality"/>
</type>
<isModifier value="false"/>
</element>
<element>
<path value="Patient.identifier"/>
<short value="An identifier for this patient"/>
<definition value="An identifier for this patient."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Identifier"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/Identifier"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.active"/>
<max value="0"/>
</element>
<element>
<path value="Patient.name"/>
<short value="A name associated with the patient"/>
<definition value="A name associated with the individual."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="HumanName"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/HumanName"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.telecom"/>
<short value="A contact detail for the individual"/>
<definition value="A contact detail (e.g. a telephone number or an email address) by which the individual may be contacted."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="ContactPoint"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/ContactPoint"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.gender"/>
<short value="male | female | other | unknown"/>
<definition value="Administrative Gender - the gender that the patient is considered to have for administration and record keeping purposes."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="code"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.birthDate"/>
<short value="The date of birth for the individual"/>
<definition value="The date of birth for the individual."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="date"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.birthDate.extension"/>
<slicing>
<discriminator>
<type value="value"/>
<path value="url"/>
</discriminator>
<rules value="open"/>
</slicing>
</element>
<element>
<path value="Patient.birthDate.extension"/>
<short value="approximateBirthDate"/>
<definition value="Flag to indicate if the birthdate is approximative or not"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/birthdate-approximative"/>
</type>
<isModifier value="false"/>
</element>
<element>
<path value="Patient.deceased[x]"/>
<short value="Indicates if the individual is deceased or not"/>
<definition value="Indicates if the individual is deceased or not."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="boolean"/>
</type>
<type>
<code value="dateTime"/>
</type>
<isModifier value="true"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.address"/>
<short value="Addresses for the individual"/>
<definition value="Addresses for the individual."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Address"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/Address"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.maritalStatus"/>
<max value="0"/>
</element>
<element>
<path value="Patient.multipleBirth[x]"/>
<short value="Whether patient is part of a multiple birth"/>
<definition value="Indicates whether the patient is part of a multiple (bool) or indicates the actual birth order (integer)."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="boolean"/>
</type>
<type>
<code value="integer"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.photo"/>
<max value="0"/>
</element>
<element>
<path value="Patient.contact"/>
<max value="0"/>
</element>
<element>
<path value="Patient.animal"/>
<max value="0"/>
</element>
<element>
<path value="Patient.communication"/>
<max value="0"/>
</element>
<element>
<path value="Patient.generalPractitioner"/>
<max value="0"/>
</element>
<element>
<path value="Patient.managingOrganization"/>
<max value="0"/>
</element>
<element>
<path value="Patient.link"/>
<max value="0"/>
</element>
</snapshot>
</StructureDefinition>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,455 @@
<QuestionnaireResponse xmlns="http://hl7.org/fhir">
<identifier>
<value value="1234567890"/>
</identifier>
<questionnaire>
<reference value="Questionnaire/q_jon"/>
</questionnaire>
<status value="completed"/>
<subject>
<reference value="http://fhirtest.uhn.ca/baseDstu3/Patient/proband"/>
</subject>
<author>
<reference value="http://fhirtest.uhn.ca/baseDstu3/Practitioner/f007"/>
</author>
<authored value="2016-01-08"/>
<item>
<linkId value="root"/>
<item>
<linkId value="g1"/>
<text value="CLINICAL INFORMATION"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="1.1"/>
</extension>
<linkId value="1.1"/>
<text value="Patient Clinical Information"/>
<answer>
<valueString value="Previous chest X-RAY was suspicious. Heavy smoker, 15 pack years."/>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="1.2"/>
</extension>
<linkId value="1.2"/>
<text value="Previous Examination (Date and Modality)"/>
<answer>
<valueString value="Chest XR - September 23, 2015"/>
</answer>
</item>
</item>
<item>
<linkId value="g2"/>
<text value="IMAGING PROCEDURE DESCRIPTION"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="2.1"/>
</extension>
<linkId value="2.1"/>
<text value="Overall Image Quality:"/>
<answer>
<valueCoding>
<code value="2.1a"/>
<display value="Adequate"/>
</valueCoding>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="2.2"/>
</extension>
<linkId value="2.2"/>
<text value="Intravenous Contrast Used?"/>
<answer>
<valueBoolean value="false"/>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="2.3"/>
</extension>
<linkId value="2.3"/>
<text value="Additional Comments"/>
<answer>
<valueString value="n/a."/>
</answer>
</item>
</item>
<item>
<linkId value="g3"/>
<text value="FINDINGS"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3"/>
</extension>
<linkId value="g3.0"/>
<text value="T Category"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.1"/>
</extension>
<linkId value="g3.1"/>
<text value="Location of Main Nodule/Mass (Primary tumor, or Reference tumor)"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.1.1"/>
</extension>
<linkId value="q3.1.1"/>
<text value="Location of main nodule/mass:"/>
<answer>
<valueCoding>
<code value="3.1.1a"/>
<display value="Peripheral"/>
</valueCoding>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.1.2"/>
</extension>
<linkId value="3.1.2"/>
<answer>
<valueString value="Right Upper Lung, Posterior segment."/>
</answer>
</item>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.2"/>
</extension>
<linkId value="g3.2"/>
<text value="Size and characteristics of main nodule/mass"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.2.1"/>
</extension>
<linkId value="3.2.1"/>
<text value="Size of the nodule/mass:"/>
<answer>
<valueCoding>
<code value="3.2.1a"/>
<display value="Solid nodule/mass"/>
</valueCoding>
</answer>
<item><!-- Measurement, image, series, etc for all 3 answer choices goes here. Conditonal. -->
<linkId value="g3.2.1"/>
<item><!-- Group for answer choice a -->
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen"><!-- Note that this extension is at the group level. -->
<extension url="#question">
<valueString value="3.2.1"/>
</extension>
<extension url="#answer">
<valueCoding>
<code value="3.2.1a"/>
</valueCoding>
</extension>
</extension>
<linkId value="g3.2.1a"/>
<item>
<linkId value="3.2.1a"/>
<text value="largest dimension:"/>
<answer>
<valueInteger value="20"/>
</answer>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl">
<valueCodeableConcept>
<coding>
<system value="http://hl7.org/fhir/ValueSet/questionnaire-item-control"/>
<code value="unit"/>
</coding>
</valueCodeableConcept>
</extension>
<text value="mm"/>
</item>
</item>
<item>
<linkId value="3.2.1a.image"/>
<text value="image"/>
<answer>
<valueString value="32"/>
</answer>
</item>
<item>
<linkId value="3.2.1a.series"/>
<text value="series"/>
<answer>
<valueString value="3"/>
</answer>
</item>
</item>
</item>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.2.2"/>
</extension>
<linkId value="3.2.2"/>
<text value="Plane in which the mass was measured:"/>
<answer>
<valueCoding>
<code value="3.2.2a"/>
<display value="Axial"/>
</valueCoding>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.2.3"/>
</extension>
<linkId value="3.2.3"/>
<answer>
<valueString value="Solid attenuation of mass, margins spiculated."/>
</answer>
</item>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.3"/>
</extension>
<linkId value="g3.3"/>
<text value="Structures directly involved"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.3.1"/>
</extension>
<linkId value="3.3.1"/>
<text value="State if there is bronchial involvement:"/>
<answer>
<valueCoding>
<code value="3.3.1b"/>
<display value="No"/>
</valueCoding>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.3.2"/>
</extension>
<linkId value="3.3.2"/>
<text value="Is there direct involvement of any other anatomical structures?"/>
<answer>
<valueBoolean value="false"/>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.3.3"/>
</extension>
<linkId value="3.3.3"/>
<text value="Are there additional suspicious pulmonary nodules?"/>
<answer>
<valueBoolean value="false"/>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="3.3.4"/>
</extension>
<linkId value="3.3.4"/>
<text value="Other notable intrathoracic findings (eg lymphangitis carcinomatosis):"/>
<answer>
<valueString value="n/a"/>
</answer>
</item>
</item>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="4"/>
</extension>
<linkId value="4.0"/>
<text value="N Category"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="4.1"/>
</extension>
<linkId value="4.1"/>
<text value="Are there enlarged lymph nodes?"/>
<answer>
<valueBoolean value="false"/>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="4.2"/>
</extension>
<linkId value="4.2"/>
<text value="Other notable findings:"/>
<answer>
<valueString value="Liner / scar atelectasis lingua, anterior segment of right upper lobe and bilateral lower lobes."/>
</answer>
</item>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="5"/>
</extension>
<linkId value="5.0"/>
<text value="M Category (Suspicious Extrathoracic Findings (M1b))"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="5.1"/>
</extension>
<linkId value="5.1"/>
<text value="Are there suspicious extrathoracic findings?"/>
<answer>
<valueBoolean value="true"/>
</answer>
<item>
<linkId value="g5.1.yes"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen">
<extension url="#question">
<valueString value="5.1"/>
</extension>
<extension url="#answer">
<valueBoolean value="true"/>
</extension>
</extension>
<linkId value="5.1.yes"/>
<text value="Applicable Structures and Descriptions:"/>
<answer>
<valueCoding>
<code value="5.1.yes.d"/>
<display value="Other"/>
</valueCoding>
</answer>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen">
<extension url="#question">
<valueString value="5.1.yes"/>
</extension>
<extension url="#answer">
<valueCoding>
<code value="5.1.yes.d"/>
</valueCoding>
</extension>
</extension>
<linkId value="5.1.yes.d.description"/>
<text value="Description of structures:"/>
<answer>
<valueString value="3 cm calcified thyroid nodule on TUL left."/>
</answer>
</item>
</item>
</item>
</item>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="6"/>
</extension>
<linkId value="6.0"/>
<text value="Additional Findings"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="6.1"/>
</extension>
<linkId value="6.1"/>
<text value="Are there additional findings?"/>
<answer>
<valueBoolean value="true"/>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="6.2"/>
</extension>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-enableWhen">
<extension url="#question">
<valueString value="6.1"/>
</extension>
<extension url="#answer">
<valueBoolean value="true"/>
</extension>
</extension>
<linkId value="6.2"/>
<text value="Findings and Descriptions:"/>
<answer>
<valueString value="Oligemic changes in right upper lobe from possible old pulmonary embolus."/>
</answer>
</item>
</item>
</item>
<item>
<linkId value="g7"/>
<text value="IMPRESSIONS"/>
<item>
<linkId value="g7.1"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="7.1"/>
</extension>
<linkId value="7.1"/>
<text value="Impression/Summary:"/>
<answer>
<valueString value="Spiculated mass in posterior segment of right upper lobe that has increasing size from 16 to 20 mm."/>
</answer>
</item>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="7.2"/>
</extension>
<linkId value="g7.2"/>
<text value="Radiologic Staging (TNM Version 7th edition)"/>
<item>
<linkId value="g7.20"/>
<text value="If this is a biopsy proven carcinoma, the preliminary radiologic stage is:"/>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="i)"/>
</extension>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-questionControl" >
<valueCodeableConcept>
<coding>
<code value="radio-button"/>
<display value="Radio Button"/>
</coding>
</valueCodeableConcept>
</extension>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-choiceOrientation" >
<valueCode value="horizontal"/>
</extension>
<linkId value="7.2i"/>
<text value="Primary Tumour (T):"/>
<answer>
<valueCoding>
<code value="T1a"/>
<display value="T1a"/>
</valueCoding>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="ii)"/>
</extension>
<linkId value="7.2ii"/>
<text value="Regional Lymph Nodes (N):"/>
<answer>
<valueCoding>
<code value="N0"/>
<display value="N0"/>
</valueCoding>
</answer>
</item>
<item>
<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-label">
<valueString value="iii)"/>
</extension>
<linkId value="7.2iii"/>
<text value="Distant Metastasis (M):"/>
<answer>
<valueCoding>
<code value="M0"/>
<display value="M0"/>
</valueCoding>
</answer>
</item>
</item>
</item>
</item>
</item>
</QuestionnaireResponse>

View File

@ -0,0 +1,298 @@
{
"resourceType": "TestScript",
"id": "search",
"text": {
"status": "generated",
"div": "<div><p><b>Generated Narrative with Details</b></p><p><b>id</b>: search</p><p><b>name</b>: Read, Search and Conditional Create and Delete</p><p><b>description</b>: Test Script for testing search, read, and conditional create and delete</p><h3>Fixtures</h3><table><tr><td>-</td><td><b>Resource</b></td></tr><tr><td>*</td><td><a>Patient/patient-example.xml</a></td></tr></table><blockquote><p><b>variable</b></p><p><b>name</b>: V1</p><p><b>sourceId</b>: R1</p><p><b>headerField</b>: Location</p></blockquote><blockquote><p><b>variable</b></p><p><b>name</b>: V2</p><p><b>sourceId</b>: R3</p><p><b>path</b>: fhir:Patient/fhir:name/fhir:given/@value</p></blockquote><blockquote><p><b>setup</b></p><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td><td><b>Type</b></td><td><b>Resource</b></td><td><b>Params</b></td></tr><tr><td>*</td><td>delete</td><td>Patient</td><td>given=John&amp;family=Doe</td></tr></table></blockquote></blockquote><blockquote><p><b>test</b></p><p><b>name</b>: Create</p><p><b>description</b>: Create, read, search, conditional create, conditional delete.</p><blockquote><p><b>metadata</b></p><h3>Links</h3><table><tr><td>-</td><td><b>Url</b></td><td><b>Description</b></td></tr><tr><td>*</td><td><a>http://hl7.org/implement/standards/FHIR-Develop/patient.html</a></td><td>FHIR Patient</td></tr></table><blockquote><p><b>operation</b></p><p><b>type</b>: create</p><p><b>resource</b>: Patient</p><p><b>description</b>: Conditional Create Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.13.1</a></p><p><b>required</b>: true</p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: delete</p><p><b>resource</b>: Patient</p><p><b>description</b>: Conditional Delete Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.12.1</a></p><p><b>required</b>: true</p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: read</p><p><b>resource</b>: Patient</p><p><b>description</b>: Patient Read Operation</p><p><b>link</b>: <a>http://hl7.org/implement/standards/FHIR-Develop/http.html#read</a></p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: search</p><p><b>resource</b>: Patient</p><p><b>description</b>: Patient Search Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.14</a></p><p><b>validated</b>: true</p></blockquote></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote></blockquote></div>"
},
"url": "http://hl7.org/fhir/TestScript/search",
"name": "Read, Search and Conditional Create and Delete",
"status": "draft",
"description": "Test Script for testing search, read, and conditional create and delete",
"metadata": {
"capability": [
{
"required": true,
"description": "Patient Create and Read Operations",
"link": [
"http://hl7.org/implement/standards/FHIR-Develop/http.html#create",
"http://hl7.org/implement/standards/FHIR-Develop/http.html#read"
],
"conformance": {
"reference": "Conformance/example"
}
},
{
"required": true,
"description": "Patient Conditional Delete Operation",
"link": [
"http://hl7-fhir.github.io/http.html#2.1.0.12.1"
],
"conformance": {
"reference": "Conformance/example"
}
},
{
"required": true,
"description": "Patient Conditional Create Operation",
"link": [
"http://hl7-fhir.github.io/http.html#2.1.0.13.1"
],
"conformance": {
"reference": "Conformance/example"
}
}
]
},
"fixture": [
{
"id": "example-patient",
"resource": {
"reference": "Patient/example"
}
}
],
"variable": [
{
"name": "V1",
"headerField": "Location",
"sourceId": "R1"
},
{
"name": "V2",
"path": "fhir:Patient/fhir:name/fhir:given/@value",
"sourceId": "R3"
},
{
"name": "DefaultValue",
"defaultValue": "Replace at Runtime"
}
],
"setup": {
"action": [
{
"fhir_comments": [
" Conditional Delete "
],
"operation": {
"type": {
"code": "delete"
},
"resource": "Patient",
"params": "given=John&family=Doe"
}
}
]
},
"test": [
{
"id": "Test1",
"name": "Create",
"description": "Create, read, search, conditional create, conditional delete.",
"metadata": {
"link": [
{
"url": "http://hl7.org/implement/standards/FHIR-Develop/patient.html",
"description": "FHIR Patient"
}
],
"capability": [
{
"validated": true,
"description": "Patient Search Operation",
"link": [
"http://hl7.org/implement/standards/FHIR-Develop/http.html#search"
],
"conformance": {
"reference": "Conformance/example"
}
}
]
},
"action": [
{
"fhir_comments": [
" Create the patient using fixture "
],
"operation": {
"type": {
"code": "create"
},
"sourceId": "example-patient"
}
},
{
"assert": {
"responseCode": "201"
}
},
{
"fhir_comments": [
" Patient search by name. Save the responseBody in 'F1' fixture.\n\t\t\t\tSave the responseHeader in H1 "
],
"operation": {
"type": {
"code": "search"
},
"resource": "Patient",
"contentType": "json",
"params": "?given=John&family=Doe",
"responseId": "R1"
}
},
{
"fhir_comments": [
" Verify that the Location in response-header is valid "
],
"assert": {
"headerField": "Location",
"operator": "notEmpty",
"warningOnly": true
}
},
{
"fhir_comments": [
" Verify that the birthdate got persisted and is being returned properly "
],
"assert": {
"operator": "equals",
"path": "fhir:Patient/fhir:birthDate/@value",
"sourceId": "R1",
"value": "1974-12-31"
}
},
{
"fhir_comments": [
" Verify that the navigation links are valid "
],
"assert": {
"navigationLinks": true,
"warningOnly": true
}
},
{
"fhir_comments": [
" Use the Location returned earlier to grab the resource\n\t\t \t\tto verify that Location was pointing to correct resource. "
],
"operation": {
"type": {
"code": "search"
},
"accept": "json",
"responseId": "R2",
"url": "${V1}"
}
},
{
"assert": {
"contentType": "json"
}
},
{
"assert": {
"response": "okay"
}
},
{
"fhir_comments": [
" Search for the resource but this time using the birthdate\n\t\t\t\tas a search parameter to make sure search by birthDate works "
],
"operation": {
"type": {
"code": "search"
},
"resource": "Patient",
"accept": "json",
"params": "?given=John&family=Doe&birthdate=1974-12-31",
"responseId": "R3"
}
},
{
"assert": {
"contentType": "json"
}
},
{
"assert": {
"response": "okay"
}
},
{
"fhir_comments": [
" Verify that the birthDate matches expectations "
],
"assert": {
"compareToSourceId": "R2",
"compareToSourcePath": "fhir:Patient/fhir:birthDate/@value",
"path": "fhir:Patient/fhir:birthDate/@value",
"sourceId": "R3"
}
},
{
"fhir_comments": [
" Verify that the name matches expectations "
],
"assert": {
"path": "fhir:Patient/fhir:name/fhir:given/@value",
"sourceId": "R3",
"value": "John"
}
},
{
"fhir_comments": [
" Conditional Create "
],
"operation": {
"type": {
"code": "create"
},
"requestHeader": [
{
"field": "If-None-Exist",
"value": "Patient?given=John&Doe&birthdate=1974-12-31"
}
],
"sourceId": "F1"
}
},
{
"fhir_comments": [
" The response code of 200 verifies that the resource\n\t\t\t\talready exists and did not get created "
],
"assert": {
"responseCode": "200"
}
},
{
"fhir_comments": [
" Conditional Delete "
],
"operation": {
"type": {
"code": "delete"
},
"resource": "Patient",
"params": "?given=John&family=Doe&birthdate=1974-12-31"
}
},
{
"fhir_comments": [
" Search again and make sure the patient has been deleted.\n\t\t \t\t This time perform read by id using variable "
],
"operation": {
"type": {
"code": "read"
},
"resource": "Patient",
"params": "/${V2}"
}
},
{
"assert": {
"responseCode": "410"
}
}
]
}
]
}