Fixes from Montreal connectathon

This commit is contained in:
James Agnew 2016-05-07 14:24:33 -04:00
parent 848ad158e2
commit af2b702aa4
39 changed files with 677 additions and 631 deletions

View File

@ -41,6 +41,8 @@ import ca.uhn.fhir.util.XmlUtil;
@DatatypeDef(name = "xhtml")
public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
private static final String DECL_XMLNS = " xmlns=\"http://www.w3.org/1999/xhtml\"";
private static final String DIV_OPEN_FIRST = "<div" + DECL_XMLNS + ">";
private static final long serialVersionUID = 1L;
/**
@ -95,12 +97,14 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
protected List<XMLEvent> parse(String theValue) {
String val = theValue.trim();
if (!val.startsWith("<")) {
val = "<div>" + val + "</div>";
val = DIV_OPEN_FIRST + val + "</div>";
}
if (val.startsWith("<?") && val.endsWith("?>")) {
boolean hasProcessingInstruction = val.startsWith("<?");
if (hasProcessingInstruction && val.endsWith("?>")) {
return null;
}
try {
ArrayList<XMLEvent> value = new ArrayList<XMLEvent>();
StringReader reader = new StringReader(val);
@ -143,11 +147,29 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
super.setValueAsString(null);
} else {
String value = theValue.trim();
if (value.charAt(0) != '<') {
value = "<div>" + value + "</div>";
}
value = preprocessXhtmlNamespaceDeclaration(value);
super.setValueAsString(value);
}
}
public static String preprocessXhtmlNamespaceDeclaration(String value) {
if (value.charAt(0) != '<') {
value = DIV_OPEN_FIRST + value + "</div>";
}
boolean hasProcessingInstruction = value.startsWith("<?");
int firstTagIndex = value.indexOf("<", hasProcessingInstruction ? 1 : 0);
if (firstTagIndex != -1) {
int firstTagEnd = value.indexOf(">", firstTagIndex);
if (firstTagEnd != -1) {
String firstTag = value.substring(firstTagIndex, firstTagEnd);
if (!firstTag.contains(" xmlns")) {
value = value.substring(0, firstTagEnd) + DECL_XMLNS + value.substring(firstTagEnd);
}
}
}
return value;
}
}

View File

@ -202,6 +202,7 @@ public class ExampleDataUploader extends BaseCommand {
ourLog.info("Downloading from remote url: {}", specUrl);
downloadFileFromInternet(result, exampleFileDownloading);
FileUtils.deleteQuietly(inputFile);
FileUtils.moveFile(exampleFileDownloading, inputFile);
if(!cacheFile) {

View File

@ -11,6 +11,7 @@ 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.Conformance;
import org.hl7.fhir.dstu3.model.IdType;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@ -176,98 +177,79 @@ public class ValidationDataUploader extends BaseCommand {
ourLog.info("Uploading definitions to server: " + targetServer);
long start = System.currentTimeMillis();
int total = 0;
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/instance/model/dstu3/valueset/"+"valuesets.xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
org.hl7.fhir.dstu3.model.Bundle bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
// String vsContents;
// try {
// ctx.getVersion().getPathToSchemaDefinitions();
// vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/valueset/"+"valuesets.xml"), "UTF-8");
// } catch (IOException e) {
// throw new CommandFailureException(e.toString());
// }
// org.hl7.fhir.dstu3.model.Bundle bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
//
// 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 ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
// try {
// client.update().resource(next).execute();
// } catch (UnprocessableEntityException e) {
// ourLog.warn("UnprocessableEntityException: " + e.toString());
// }
// count++;
// }
//
// try {
// vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/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);
// 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() });
// client.update().resource(next).execute();
//
// count++;
// }
//
// try {
// vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/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);
// 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.setId(next.getIdElement().toUnqualifiedVersionless());
//
// ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
// client.update().resource(next).execute();
// count++;
// }
//
// ourLog.info("Finished uploading ValueSets");
int total = bundle.getEntry().size();
int count = 1;
for (BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
try {
client.update().resource(next).execute();
} catch (UnprocessableEntityException e) {
ourLog.warn("UnprocessableEntityException: " + e.toString());
}
count++;
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/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);
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() });
client.update().resource(next).execute();
count++;
}
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/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);
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.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading v2-tables ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
client.update().resource(next).execute();
count++;
}
ourLog.info("Finished uploading ValueSets");
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
Resource[] mappingLocations;
try {
mappingLocations = patternResolver.getResources("classpath*:org/hl7/fhir/instance/model/dstu3/*.xml");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
total = mappingLocations.length;
count = 1;
for (Resource i : mappingLocations) {
try {
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, new InputStreamReader(i.getInputStream()));
} catch (Exception e1) {
throw new CommandFailureException(e1.toString());
}
total = bundle.getEntry().size();
count = 1;
for (BundleEntryComponent e : bundle.getEntry()) {
org.hl7.fhir.dstu3.model.StructureDefinition next = (org.hl7.fhir.dstu3.model.StructureDefinition) e.getResource();
next.setId(next.getIdElement().toUnqualifiedVersionless());
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] { i.getFilename(), count, total, next.getIdElement().getValue() });
client.update().resource(next).execute();
count++;
}
}
uploadDstu3Profiles(ctx, client, "profiles-resources");
uploadDstu3Profiles(ctx, client, "profiles-types");
uploadDstu3Profiles(ctx, client, "profiles-others");
ourLog.info("Finished uploading ValueSets");
@ -276,4 +258,33 @@ public class ValidationDataUploader extends BaseCommand {
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
}
private void uploadDstu3Profiles(FhirContext ctx, IGenericClient client, String name) throws CommandFailureException {
int total;
int count;
org.hl7.fhir.dstu3.model.Bundle bundle;
ourLog.info("Uploading " + name);
String vsContents;
try {
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/profile/" + name + ".xml"), "UTF-8");
} catch (IOException e) {
throw new CommandFailureException(e.toString());
}
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
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());
if (next instanceof Conformance) {
continue;
}
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] { name, count, total, next.getIdElement().getValue() });
client.update().resource(next).execute();
count++;
}
}
}

View File

@ -1406,7 +1406,7 @@ public class GenericJaxRsClientDstu2Test {
assertEquals("http://localhost:" + ourPort + "/fhir/Patient/123?_summary=text", ourRequestUri);
assertEquals(Patient.class, response.getClass());
assertEquals("<div>HELP IM A DIV</div>", response.getText().getDiv().getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELP IM A DIV</div>", response.getText().getDiv().getValueAsString());
}

View File

@ -1407,7 +1407,7 @@ public class GenericJaxRsClientDstu3Test {
assertEquals("http://localhost:" + ourPort + "/fhir/Patient/123?_summary=text", ourRequestUri);
assertEquals(Patient.class, response.getClass());
assertEquals("<div>HELP IM A DIV</div>", response.getText().getDiv().getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELP IM A DIV</div>", response.getText().getDiv().getValueAsString());
}

View File

@ -142,6 +142,7 @@ import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
@ -241,12 +242,12 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return InstantDt.withCurrentTime();
}
@SuppressWarnings("unchecked")
protected Set<ResourceLink> extractResourceLinks(ResourceTable theEntity, IBaseResource theResource) {
Set<ResourceLink> retVal = new HashSet<ResourceLink>();
/*
* For now we don't try to load any of the links in a bundle if it's the
* actual bundle we're storing..
* For now we don't try to load any of the links in a bundle if it's the actual bundle we're storing..
*/
if (theResource instanceof IBaseBundle) {
return retVal;
@ -290,7 +291,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
if (nextId == null || nextId.hasIdPart() == false) {
continue;
}
} else if (myContext.getElementDefinition((Class<? extends IBase>) nextObject.getClass()).getName().equals("uri")) {
continue;
} else {
if (!multiType) {
if (nextSpDef.getName().equals("sourceuri")) {
@ -1251,11 +1253,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
Set<Long> matches = processMatchUrl(nextIdText, matchResourceType);
if (matches.isEmpty()) {
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirDao.class, "invalidMatchUrlNoMatches", nextId.getValue());
throw new InvalidRequestException(msg);
throw new ResourceNotFoundException(msg);
}
if (matches.size() > 1) {
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirDao.class, "invalidMatchUrlMultipleMatches", nextId.getValue());
throw new InvalidRequestException(msg);
throw new PreconditionFailedException(msg);
}
Long next = matches.iterator().next();
String newId = translatePidIdToForcedId(resourceTypeString, next);
@ -1519,12 +1521,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
for (IBase nextChild : values) {
IBaseReference nextRef = (IBaseReference) nextChild;
if (!isBlank(nextRef.getReferenceElement().getResourceType())) {
if (!nextRef.getReferenceElement().getValue().contains("?")) {
if (!validTypes.contains(nextRef.getReferenceElement().getResourceType())) {
throw new UnprocessableEntityException(
"Invalid reference found at path '" + newPath + "'. Resource type '" + nextRef.getReferenceElement().getResourceType() + "' is not valid for this path");
}
}
}
}
}
}

View File

@ -39,7 +39,7 @@ import org.hibernate.annotations.ColumnDefault;
@UniqueConstraint(name = "IDX_FORCEDID_RESID", columnNames = {"RESOURCE_PID"}),
@UniqueConstraint(name = "IDX_FORCEDID_TYPE_RESID", columnNames = {"RESOURCE_TYPE", "RESOURCE_PID"})
}, indexes= {
@Index(name = "IDX_FORCEDID", columnList = "FORCED_ID"),
@Index(name = "IDX_FORCEDID_TYPE_FORCEDID", columnList = "RESOURCE_TYPE,FORCED_ID"),
})
//@formatter:on
public class ForcedId {

View File

@ -17,6 +17,7 @@ import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.CompartmentDefinition;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.Device;
import org.hl7.fhir.dstu3.model.DiagnosticOrder;
@ -30,6 +31,7 @@ import org.hl7.fhir.dstu3.model.MedicationOrder;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.NamingSystem;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.OperationDefinition;
import org.hl7.fhir.dstu3.model.Organization;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.Practitioner;
@ -176,6 +178,12 @@ protected IFhirResourceDao<Observation> myObservationDao;
@Qualifier("myStructureDefinitionDaoDstu3")
protected IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
@Autowired
@Qualifier("myCompartmentDefinitionDaoDstu3")
protected IFhirResourceDao<CompartmentDefinition> myCompartmentDefinitionDao;
@Autowired
@Qualifier("myOperationDefinitionDaoDstu3")
protected IFhirResourceDao<OperationDefinition> myOperationDefinitionDao;
@Autowired
@Qualifier("mySubscriptionDaoDstu3")
protected IFhirResourceDaoSubscription<Subscription> mySubscriptionDao;
@Autowired

View File

@ -9,7 +9,6 @@ import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@ -32,19 +31,19 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.hamcrest.Matchers;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.dstu3.model.BaseResource;
import org.hl7.fhir.dstu3.model.Bundle;
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.CodeType;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.CompartmentDefinition;
import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.DateType;
@ -56,6 +55,7 @@ import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.NamingSystem;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.OperationDefinition;
import org.hl7.fhir.dstu3.model.OperationOutcome;
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueType;
@ -67,11 +67,13 @@ import org.hl7.fhir.dstu3.model.Quantity.QuantityComparator;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.UriType;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@ -109,7 +111,6 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.TestUtil;
@SuppressWarnings("unchecked")
@ -131,6 +132,34 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
}
}
@Test
@Ignore
public void testCreateBuiltInProfiles() throws Exception {
org.hl7.fhir.dstu3.model.Bundle bundle;
String name = "profiles-resources";
ourLog.info("Uploading " + name);
String vsContents;
vsContents = IOUtils.toString(FhirResourceDaoDstu3Test.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/profile/" + name + ".xml"), "UTF-8");
bundle = myFhirCtx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
for (BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
ourLog.debug(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(next));
if (next instanceof StructureDefinition) {
myStructureDefinitionDao.update((StructureDefinition) next, mySrd);
} else if (next instanceof CompartmentDefinition) {
myCompartmentDefinitionDao.update((CompartmentDefinition) next, mySrd);
} else if (next instanceof OperationDefinition) {
myOperationDefinitionDao.update((OperationDefinition) next, mySrd);
} else {
fail(next.getClass().getName());
}
}
}
/**
* This gets called from assertGone too! Careful about exceptions...
*/

View File

@ -17,6 +17,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
@ -333,6 +334,62 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
}
@Test
public void testTransactionWithInlineMatchUrl() throws Exception {
myDaoConfig.setAllowInlineMatchUrlReferences(true);
Patient patient = new Patient();
patient.addIdentifier().setSystem("http://www.ghh.org/identifiers").setValue("condreftestpatid1");
myPatientDao.create(patient, mySrd);
String input = IOUtils.toString(getClass().getResourceAsStream("/simone-conditional-url.xml"));
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
Bundle response = mySystemDao.transaction(mySrd, bundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
}
@Test
public void testTransactionWithInlineMatchUrlMultipleMatches() throws Exception {
myDaoConfig.setAllowInlineMatchUrlReferences(true);
Patient patient = new Patient();
patient.addIdentifier().setSystem("http://www.ghh.org/identifiers").setValue("condreftestpatid1");
myPatientDao.create(patient, mySrd);
patient = new Patient();
patient.addIdentifier().setSystem("http://www.ghh.org/identifiers").setValue("condreftestpatid1");
myPatientDao.create(patient, mySrd);
String input = IOUtils.toString(getClass().getResourceAsStream("/simone-conditional-url.xml"));
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
try {
mySystemDao.transaction(mySrd, bundle);
fail();
} catch (PreconditionFailedException e) {
assertEquals("Invalid match URL \"Patient?identifier=http://www.ghh.org/identifiers|condreftestpatid1\" - Multiple resources match this search", e.getMessage());
}
}
@Test
public void testTransactionWithInlineMatchUrlNoMatches() throws Exception {
myDaoConfig.setAllowInlineMatchUrlReferences(true);
String input = IOUtils.toString(getClass().getResourceAsStream("/simone-conditional-url.xml"));
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
try {
mySystemDao.transaction(mySrd, bundle);
fail();
} catch (ResourceNotFoundException e) {
assertEquals("Invalid match URL \"Patient?identifier=http://www.ghh.org/identifiers|condreftestpatid1\" - No resources match this search", e.getMessage());
}
}
@Test
public void testTransactionCreateMatchUrlWithOneMatch() {
String methodName = "testTransactionCreateMatchUrlWithOneMatch";

View File

@ -1390,7 +1390,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
IIdType newId = ourClient.create().resource(p1).encodedJson().execute().getId();
Patient actual = ourClient.read().resource(Patient.class).withId(newId).encodedJson().execute();
assertEquals("<div>HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
@Test

View File

@ -1445,7 +1445,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
IIdType newId = ourClient.create().resource(p1).encodedJson().execute().getId();
Patient actual = ourClient.read().resource(Patient.class).withId(newId).encodedJson().execute();
assertEquals("<div>HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
@Test
@ -1458,7 +1458,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
IIdType newId = ourClient.create().resource(p1).encodedXml().execute().getId();
Patient actual = ourClient.read().resource(Patient.class).withId(newId).encodedXml().execute();
assertEquals("<div>HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
@Test

View File

@ -0,0 +1,96 @@
<Bundle xmlns="http://hl7.org/fhir">
<id value="20160507105037" />
<type value="transaction" />
<entry>
<resource>
<AllergyIntolerance>
<meta>
<tag>
<code value="CLOVERLEAF" />
</tag>
</meta>
<identifier>
<system value="http://health-comm.de/identifiers" />
<value value="condreftestpatid1-DA-1605" />
<assigner>
<display value="CLOVERLEAF" />
</assigner>
</identifier>
<patient>
<reference value="Patient?identifier=http://www.ghh.org/identifiers|condreftestpatid1" />
<display value="Kennedy, Ann(*24.05.1928)" />
</patient>
<substance>
<coding>
<code value="1605" />
<display value="L" />
</coding>
<text value="acetaminophen" />
</substance>
<category value="medication" />
<reaction>
<manifestation>
<text value="Muscle Pain" />
</manifestation>
<severity value="moderate" />
</reaction>
<reaction>
<manifestation>
<text value="hair loss" />
</manifestation>
<severity value="moderate" />
</reaction>
</AllergyIntolerance>
</resource>
<request>
<method value="PUT" />
<url value="AllergyIntolerance?identifier=http://health-comm.de/identifiers|condreftestpatid1-DA-1605" />
</request>
</entry>
<entry>
<request>
<method value="DELETE" />
<url value="AllergyIntolerance?patient.identifier=http://www.ghh.org/identifiers|condreftestpatid1&amp;_tag=CLOVERLEAF" />
</request>
</entry>
<entry>
<resource>
<AllergyIntolerance>
<meta>
<tag>
<code value="CLOVERLEAF" />
</tag>
</meta>
<identifier>
<system value="http://health-comm.de/identifiers" />
<value value="condreftestpatid1-MA-2221" />
<assigner>
<display value="CLOVERLEAF" />
</assigner>
</identifier>
<patient>
<reference value="Patient?identifier=http://www.ghh.org/identifiers|condreftestpatid1" />
<display value="Kennedy, Ann(*24.05.1928)" />
</patient>
<substance>
<coding>
<code value="2221" />
<display value="L" />
</coding>
<text value="Peanuts" />
</substance>
<category value="environment" />
<reaction>
<manifestation>
<text value="Anaphylactic Shock" />
</manifestation>
<severity value="severe" />
</reaction>
</AllergyIntolerance>
</resource>
<request>
<method value="PUT" />
<url value="AllergyIntolerance?identifier=http://health-comm.de/identifiers|condreftestpatid1-MA-2221" />
</request>
</entry>
</Bundle>

View File

@ -167,9 +167,21 @@
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<webApp>
<contextPath>/</contextPath>
<allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
</webApp>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>

View File

@ -15,7 +15,7 @@ public class XhtmlDtTest {
@Test
public void testRoundtripTiny() {
String div = "<div>xmlns=&quot;http://hl7.org/fhir&quot;</div>";
String div = "<div xmlns=\"http://www.w3.org/1999/xhtml\">xmlns=&quot;http://hl7.org/fhir&quot;</div>";
XhtmlDt x = new XhtmlDt();
x.setValueAsString(div);
@ -31,7 +31,7 @@ public class XhtmlDtTest {
@Test
public void testRoundtrip() {
String div = "<div><pre>\r\n&lt;<a title=\"Prospective warnings of potential issues when providing care to the patient.\" class=\"dict\" href=\"alert-definitions.html#Alert\"><b>Alert</b></a> xmlns=&quot;http://hl7.org/fhir&quot;&gt; <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n &lt;!-- from <a href=\"resources.html\">Resource</a>: <a href=\"extensibility.html\">extension</a>, <a href=\"extensibility.html#modifierExtension\">modifierExtension</a>, language, <a href=\"narrative.html#Narrative\">text</a>, and <a href=\"references.html#contained\">contained</a> --&gt;\r\n &lt;<a title=\"Identifier assigned to the alert for external use (outside the FHIR environment).\" class=\"dict\" href=\"alert-definitions.html#Alert.identifier\"><b>identifier</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..*</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#Identifier\">Identifier</a></span> <span style=\"color: navy\">Business identifier</span><span style=\"color: Gray\"> --&gt;</span>&lt;/identifier&gt;\r\n &lt;<a title=\"Allows an alert to be divided into different categories like clinical, administrative etc.\" class=\"dict\" href=\"alert-definitions.html#Alert.category\"><b>category</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#CodeableConcept\">CodeableConcept</a></span> <span style=\"color: navy\">Clinical, administrative, etc.</span><span style=\"color: Gray\"> --&gt;</span>&lt;/category&gt;\r\n &lt;<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\"><a style=\"color: navy\" href=\"alert-status.html\">active | inactive | entered in error</a></span><span style=\"color: Gray\"> --&gt;</span>\r\n &lt;<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"patient.html#Patient\">Patient</a>)</span> <span style=\"color: navy\">Who is alert about?</span><span style=\"color: Gray\"> --&gt;</span>&lt;/subject&gt;\r\n &lt;<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"practitioner.html#Practitioner\">Practitioner</a>|<a href=\"patient.html#Patient\">Patient</a>|<a href=\"device.html#Device\">Device</a>)</span> <span style=\"color: navy\">Alert creator</span><span style=\"color: Gray\"> --&gt;</span>&lt;/author&gt;\r\n &lt;<a title=\"The textual component of the alert to display to the user.\" class=\"dict\" href=\"alert-definitions.html#Alert.note\"><b>note</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --&gt;</span>\r\n&lt;/Alert&gt;\r\n</pre></div>";
String div = "<div xmlns=\"http://www.w3.org/1999/xhtml\"><pre>\r\n&lt;<a title=\"Prospective warnings of potential issues when providing care to the patient.\" class=\"dict\" href=\"alert-definitions.html#Alert\"><b>Alert</b></a> xmlns=&quot;http://hl7.org/fhir&quot;&gt; <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n &lt;!-- from <a href=\"resources.html\">Resource</a>: <a href=\"extensibility.html\">extension</a>, <a href=\"extensibility.html#modifierExtension\">modifierExtension</a>, language, <a href=\"narrative.html#Narrative\">text</a>, and <a href=\"references.html#contained\">contained</a> --&gt;\r\n &lt;<a title=\"Identifier assigned to the alert for external use (outside the FHIR environment).\" class=\"dict\" href=\"alert-definitions.html#Alert.identifier\"><b>identifier</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..*</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#Identifier\">Identifier</a></span> <span style=\"color: navy\">Business identifier</span><span style=\"color: Gray\"> --&gt;</span>&lt;/identifier&gt;\r\n &lt;<a title=\"Allows an alert to be divided into different categories like clinical, administrative etc.\" class=\"dict\" href=\"alert-definitions.html#Alert.category\"><b>category</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#CodeableConcept\">CodeableConcept</a></span> <span style=\"color: navy\">Clinical, administrative, etc.</span><span style=\"color: Gray\"> --&gt;</span>&lt;/category&gt;\r\n &lt;<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\"><a style=\"color: navy\" href=\"alert-status.html\">active | inactive | entered in error</a></span><span style=\"color: Gray\"> --&gt;</span>\r\n &lt;<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"patient.html#Patient\">Patient</a>)</span> <span style=\"color: navy\">Who is alert about?</span><span style=\"color: Gray\"> --&gt;</span>&lt;/subject&gt;\r\n &lt;<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"practitioner.html#Practitioner\">Practitioner</a>|<a href=\"patient.html#Patient\">Patient</a>|<a href=\"device.html#Device\">Device</a>)</span> <span style=\"color: navy\">Alert creator</span><span style=\"color: Gray\"> --&gt;</span>&lt;/author&gt;\r\n &lt;<a title=\"The textual component of the alert to display to the user.\" class=\"dict\" href=\"alert-definitions.html#Alert.note\"><b>note</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --&gt;</span>\r\n&lt;/Alert&gt;\r\n</pre></div>";
XhtmlDt x = new XhtmlDt();
x.setValueAsString(div);
@ -55,7 +55,7 @@ public class XhtmlDtTest {
XhtmlDt x = new XhtmlDt();
x.setValueAsString(input);
assertEquals("<div>amp &amp;</div>", x.getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">amp &amp;</div>", x.getValueAsString());
}
@Test
@ -75,11 +75,11 @@ public class XhtmlDtTest {
// <div>Sect: § uuml: ü Ü</div>
// <div>Sect: &sect; uuml: &uuml; &Uuml;</div>
assertEquals("<div>" + input + "</div>", x.getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">" + input + "</div>", x.getValueAsString());
XhtmlDt x2 = new XhtmlDt();
x2.setValue(x.getValue());
assertEquals("<div>&amp; Sect: § uuml: ü Ü Trade: ™</div>", x2.getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">&amp; Sect: § uuml: ü Ü Trade: ™</div>", x2.getValueAsString());
}

View File

@ -83,7 +83,7 @@ public class DefaultThymeleafNarrativeGeneratorTest {
NarrativeDt narrative = new NarrativeDt();
gen.generateNarrative(myCtx, value, narrative);
String output = narrative.getDiv().getValueAsString();
assertThat(output, StringContains.containsString("<div>"));
assertThat(output, StringContains.containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">"));
// Removed because label is gone in DSTU2
// value.getIdentifierFirstRep().setLabel("FOO MRN 123");

View File

@ -87,6 +87,8 @@ public class JsonParserTest {
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream(name));
// ourLog.info(msg);
msg = msg.replace("\"div\": \"<div>", "\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">");
IParser p = ourCtx.newJsonParser();
Profile res = p.parseResource(Profile.class, msg);
@ -469,7 +471,7 @@ public class JsonParserTest {
String str = p.encodeResourceToString(rpt);
ourLog.info(str);
assertThat(str, StringContains.containsString("<div>AAA</div>"));
assertThat(str, StringContains.containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">AAA</div>"));
String substring = "\"reference\":\"#";
assertThat(str, StringContains.containsString(substring));
@ -710,7 +712,7 @@ public class JsonParserTest {
String out = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(out);
assertThat(out, containsString("<div>hello</div>"));
assertThat(out, containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">hello</div>"));
p.getText().setDiv("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">hello</xhtml:div>");
out = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(b);
@ -968,7 +970,7 @@ public class JsonParserTest {
ourLog.info(str);
assertThat(str, StringContains.containsString(",\"text\":{\"status\":\"generated\",\"div\":\"<div>help</div>\"},"));
assertThat(str, StringContains.containsString(",\"text\":{\"status\":\"generated\",\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">help</div>\"},"));
}
@Before

View File

@ -80,6 +80,28 @@ public class JsonParserDstu2Test {
private static final FhirContext ourCtx = FhirContext.forDstu2();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserDstu2Test.class);
@Test
public void testEncodeNarrativeShouldIncludeNamespace() {
Patient p = new Patient();
p.getText().setDivAsString("<div>VALUE</div>");
String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
assertThat(output, containsString("\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">VALUE</div>\""));
}
@Test
public void testEncodeNarrativeShouldIncludeNamespaceWithProcessingInstruction() {
Patient p = new Patient();
p.getText().setDivAsString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><div>VALUE</div>");
String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
assertThat(output, containsString("\"div\":\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">VALUE</div>\""));
}
@Test
public void testContainedResourceInExtensionUndeclared() {
Patient p = new Patient();

View File

@ -1694,7 +1694,7 @@ public class GenericClientDstu2Test {
assertEquals("http://example.com/fhir/Patient/123?_summary=text", capt.getValue().getURI().toString());
assertEquals(Patient.class, response.getClass());
assertEquals("<div>HELP IM A DIV</div>", response.getText().getDiv().getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELP IM A DIV</div>", response.getText().getDiv().getValueAsString());
}

View File

@ -84,7 +84,7 @@ public class SummaryParamTest {
assertEquals(Constants.CT_HTML_WITH_UTF8.replace(" ", "").toLowerCase(), status.getEntity().getContentType().getValue().replace(" ", "").replace("UTF", "utf"));
assertThat(responseContent, not(containsString("<Bundle")));
assertThat(responseContent, not(containsString("<Medic")));
assertEquals("<div>THE DIV</div>", responseContent);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">THE DIV</div>", responseContent);
assertThat(responseContent, not(containsString("efer")));
assertEquals(SummaryEnum.TEXT, ourLastSummary);
}
@ -101,7 +101,7 @@ public class SummaryParamTest {
assertEquals(Constants.CT_HTML_WITH_UTF8.replace(" ", "").toLowerCase(), status.getEntity().getContentType().getValue().replace(" ", "").replace("UTF", "utf"));
assertThat(responseContent, not(containsString("<Bundle")));
assertThat(responseContent, not(containsString("<Patien")));
assertEquals("<div>TEXT</div>", responseContent);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">TEXT</div>", responseContent);
assertThat(responseContent, not(containsString("family")));
assertThat(responseContent, not(containsString("maritalStatus")));
}

View File

@ -35,10 +35,13 @@ import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseXhtml;
import ca.uhn.fhir.model.primitive.XhtmlDt;
@ca.uhn.fhir.model.api.annotation.DatatypeDef(name="xhtml")
public class XhtmlNode implements IBaseXhtml {
public static final String NBSP = Character.toString((char)0xa0);
private static final String DECL_XMLNS = " xmlns=\"http://www.w3.org/1999/xhtml\"";
private NodeType nodeType;
private String name;
@ -304,7 +307,9 @@ public class XhtmlNode implements IBaseXhtml {
return null;
}
try {
return new XhtmlComposer().compose(this);
String retVal = new XhtmlComposer().compose(this);
retVal = XhtmlDt.preprocessXhtmlNamespaceDeclaration(retVal);
return retVal;
} catch (Exception e) {
// TODO: composer shouldn't throw exception like this
throw new RuntimeException(e);
@ -327,12 +332,14 @@ public class XhtmlNode implements IBaseXhtml {
}
if (!val.startsWith("<")) {
val = "<div>" + val + "</div>";
val = "<div" + DECL_XMLNS +">" + val + "</div>";
}
if (val.startsWith("<?") && val.endsWith("?>")) {
return;
}
val = XhtmlDt.preprocessXhtmlNamespaceDeclaration(val);
try {
// TODO: this is ugly
XhtmlNode fragment = new XhtmlParser().parseFragment(val);

View File

@ -0,0 +1,60 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.DomainResource;
import org.hl7.fhir.dstu3.model.Narrative;
import org.hl7.fhir.dstu3.model.Resource;
import org.junit.AfterClass;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
public class MinimizeResources {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(MinimizeResources.class);
private static final FhirContext ourCtx = FhirContext.forDstu3();
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
public static void main(String[] args) throws Exception {
Collection<File> xml = FileUtils.listFiles(new File("../hapi-fhir-validation-resources-dstu3/src/main/resources/org/hl7/fhir/instance/model/dstu3/profile"), new String[] {"xml"}, false);
for (File next : xml) {
ourLog.info("Checking: {}", next.getAbsoluteFile());
String inputFile = IOUtils.toString(new FileReader(next));
Bundle bundle = (Bundle) ourCtx.newXmlParser().parseResource(inputFile);
for (BundleEntryComponent nextEntry : bundle.getEntry()) {
Resource resource;
resource = nextEntry.getResource();
if (resource instanceof DomainResource) {
((DomainResource) resource).setText(new Narrative());
}
}
String output = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(bundle);
if (!output.equals(inputFile)) {
ourLog.info("Rewriting {}", next.getAbsolutePath());
FileWriter writer = new FileWriter(next, false);
writer.append(output);
writer.close();
}
}
}
}

View File

@ -88,6 +88,29 @@ public class JsonParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
@Test
public void testEncodeNarrativeShouldIncludeNamespace() {
Patient p = new Patient();
p.getText().setDivAsString("<div>VALUE</div>");
String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
assertThat(output, containsString("\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">VALUE</div>\""));
}
@Test
public void testEncodeNarrativeShouldIncludeNamespaceWithProcessingInstruction() {
Patient p = new Patient();
p.getText().setDivAsString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><div>VALUE</div>");
String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
ourLog.info(output);
assertThat(output, containsString("\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">VALUE</div>\""));
}
/**
* See #344
*/
@ -830,7 +853,7 @@ public class JsonParserDstu3Test {
String output = ourCtx.newJsonParser().encodeResourceToString(p);
ourLog.info(output);
assertThat(output, containsString("\"text\":{\"status\":\"generated\",\"div\":\"<div><div class=\\\"hapiHeaderText\\\"> John <b>SMITH </b></div>"));
assertThat(output, containsString("\"text\":{\"status\":\"generated\",\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\"><div class=\\\"hapiHeaderText\\\"> John <b>SMITH </b></div>"));
}
@Test

View File

@ -118,7 +118,7 @@ public class GenericClientDstu3Test {
assertEquals(Constants.CT_FHIR_JSON, output.getContentType());
Patient outputPt = (Patient) ourCtx.newJsonParser().parseResource(new String(output.getContent(), "UTF-8"));
assertEquals("<div>A PATIENT</div>", outputPt.getText().getDivAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">A PATIENT</div>", outputPt.getText().getDivAsString());
}
@Test
@ -199,8 +199,8 @@ public class GenericClientDstu3Test {
assertNotNull(outcome.getOperationOutcome());
assertNotNull(outcome.getResource());
assertEquals("<div>OK!</div>", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString());
assertEquals("<div>FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals(myAnswerCount, capt.getAllValues().size());
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
@ -243,7 +243,7 @@ public class GenericClientDstu3Test {
assertNull(outcome.getOperationOutcome());
assertNotNull(outcome.getResource());
assertEquals("<div>FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals(myAnswerCount, capt.getAllValues().size());
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
@ -481,8 +481,8 @@ public class GenericClientDstu3Test {
assertNotNull(outcome.getOperationOutcome());
assertNotNull(outcome.getResource());
assertEquals("<div>OK!</div>", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString());
assertEquals("<div>FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals(myAnswerCount, capt.getAllValues().size());
assertEquals("http://example.com/fhir/Patient/222", capt.getAllValues().get(0).getURI().toASCIIString());
@ -526,7 +526,7 @@ public class GenericClientDstu3Test {
assertNull(outcome.getOperationOutcome());
assertNotNull(outcome.getResource());
assertEquals("<div>FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
assertEquals(myAnswerCount, capt.getAllValues().size());
assertEquals("http://example.com/fhir/Patient/222", capt.getAllValues().get(0).getURI().toASCIIString());

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.validation;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@ -24,6 +25,7 @@ import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
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.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.dstu3.model.CodeType;
@ -74,6 +76,28 @@ public class FhirInstanceValidatorDstu3Test {
myValidConcepts.add(theSystem + "___" + theCode);
}
@Test
// @Ignore
public void testValidateBuiltInProfiles() throws Exception {
org.hl7.fhir.dstu3.model.Bundle bundle;
String name = "profiles-resources";
ourLog.info("Uploading " + name);
String vsContents;
vsContents = IOUtils.toString(FhirInstanceValidatorDstu3Test.class.getResourceAsStream("/org/hl7/fhir/instance/model/dstu3/profile/" + name + ".xml"), "UTF-8");
bundle = ourCtx.newXmlParser().parseResource(org.hl7.fhir.dstu3.model.Bundle.class, vsContents);
for (BundleEntryComponent i : bundle.getEntry()) {
org.hl7.fhir.dstu3.model.Resource next = i.getResource();
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(next));
ValidationResult output = myVal.validateWithResult(next);
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
assertThat("Failed to validate " + i.getFullUrl(), errors, empty());
}
}
@SuppressWarnings("unchecked")
@Before
public void before() {

View File

@ -18,7 +18,7 @@ public class XhtmlNodeTest {
String output = node.getValueAsString();
ourLog.info(output);
assertEquals("<div><img src=\"http://pbs.twimg.com/profile_images/544507893991485440/r_vo3uj2_bigger.png\" alt=\"Twitter Avatar\"/>@fhirabend</div>", output);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><img src=\"http://pbs.twimg.com/profile_images/544507893991485440/r_vo3uj2_bigger.png\" alt=\"Twitter Avatar\"/>@fhirabend</div>", output);
}
@Test
@ -33,7 +33,7 @@ public class XhtmlNodeTest {
String output = node.getValueAsString();
ourLog.info(output);
assertEquals("<div><img src=\"http://pbs.twimg.com/profile_images/544507893991485440/r_vo3uj2_bigger.png\" alt=\"Twitter Avatar\"/>@fhirabend</div>", output);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\"><img src=\"http://pbs.twimg.com/profile_images/544507893991485440/r_vo3uj2_bigger.png\" alt=\"Twitter Avatar\"/>@fhirabend</div>", output);
}
}

View File

@ -29,6 +29,7 @@ import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.Bundle;
@ -236,7 +237,8 @@ public class Controller extends BaseController {
addCommonParams(theReq, theRequest, theModel);
CaptureInterceptor interceptor = new CaptureInterceptor();
GenericClient client = theRequest.newClient(theReq, getContext(theRequest), myConfig, interceptor);
FhirContext context = getContext(theRequest);
GenericClient client = theRequest.newClient(theReq, context, myConfig, interceptor);
String url = defaultString(theReq.getParameter("page-url"));
if (!url.startsWith(theModel.get("base").toString())) {
@ -252,7 +254,13 @@ public class Controller extends BaseController {
long start = System.currentTimeMillis();
try {
ourLog.info(logPrefix(theModel) + "Loading paging URL: {}", url);
client.loadPage().url(url).execute();
if (context.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
client.loadPage().byUrl(url).andReturnDstu1Bundle().execute();
} else {
@SuppressWarnings("unchecked")
Class<? extends IBaseBundle> bundleType = (Class<? extends IBaseBundle>) context.getResourceDefinition("Bundle").getImplementingClass();
client.loadPage().byUrl(url).andReturnBundle(bundleType).execute();
}
} catch (Exception e) {
returnsResource = handleClientException(client, e, theModel);
}

View File

@ -1,11 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="owner.project.facets" value="java"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="build/classes"/>
<classpathentry kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -13,6 +13,20 @@
<name>HAPI FHIR - Validation Resources (DSTU3)</name>
<dependencies>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>1.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>

View File

@ -0,0 +1,30 @@
<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

@ -129,6 +129,22 @@
was causing issues with interoperability
with the .NET client.
</action>
<action type="fix">
CLI tool cache feature (-c) for upload-example task sometimes failed
to write cache file and exited with an exception.
</action>
<action type="fix">
Fix error message in web testing UI when loading pages in a search
result for STU3 endpoints.
</action>
<action type="fix">
When encoding JSON resource, the parser will now always
ensure that XHTML narrative content has an
XHTML namespace declaration on the first
DIV tag. This was preventing validation for
some resources using the official validator
rules.
</action>
</release>
<release version="1.5" date="2016-04-20">
<action type="fix" issue="339">