Fix encoding issue on narrative blocks

This commit is contained in:
James Agnew 2014-08-28 09:44:04 -04:00
parent d205075e35
commit 46fbfeb66e
22 changed files with 352 additions and 93 deletions

View File

@ -635,6 +635,14 @@
</reportSet> </reportSet>
</reportSets> </reportSets>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-linkcheck-plugin</artifactId>
<version>1.1</version>
<configuration>
<forceSite>false</forceSite>
</configuration>
</plugin>
</plugins> </plugins>
</reporting> </reporting>
</profile> </profile>

View File

@ -131,6 +131,11 @@
java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for
reporting! reporting!
</action> </action>
<action type="fix">
Text/narrative blocks that were created with a non-empty
namespace prefix (e.g. &lt;xhtml:div xmlns:xhtml="..."&gt;...&lt;/xhtml:div&gt;)
failed to encode correctly (prefix was missing in encoded resource)
</action>
</release> </release>
<release version="0.5" date="2014-Jul-30"> <release version="0.5" date="2014-Jul-30">
<action type="add"> <action type="add">

View File

@ -259,6 +259,9 @@ public class IdDt extends BasePrimitive<String> {
* "https://" * "https://"
*/ */
public boolean isAbsolute() { public boolean isAbsolute() {
if (StringUtils.isBlank(getValue())) {
return false;
}
return UrlUtil.isAbsolute(getValue()); return UrlUtil.isAbsolute(getValue());
} }

View File

@ -652,7 +652,8 @@ public class XmlParser extends BaseParser implements IParser {
break; break;
case XMLStreamConstants.CHARACTERS: case XMLStreamConstants.CHARACTERS:
case XMLStreamConstants.SPACE: case XMLStreamConstants.SPACE:
theEventWriter.writeCharacters(((Characters) event).getData()); String data = ((Characters) event).getData();
theEventWriter.writeCharacters(data);
break; break;
case XMLStreamConstants.COMMENT: case XMLStreamConstants.COMMENT:
theEventWriter.writeComment(((Comment) event).getText()); theEventWriter.writeComment(((Comment) event).getText());
@ -671,15 +672,18 @@ public class XmlParser extends BaseParser implements IParser {
case XMLStreamConstants.START_ELEMENT: case XMLStreamConstants.START_ELEMENT:
StartElement se = event.asStartElement(); StartElement se = event.asStartElement();
if (firstEvent) { if (firstEvent) {
theEventWriter.writeStartElement(se.getName().getLocalPart());
if (StringUtils.isBlank(se.getName().getPrefix())) { if (StringUtils.isBlank(se.getName().getPrefix())) {
String namespaceURI = se.getName().getNamespaceURI(); String namespaceURI = se.getName().getNamespaceURI();
if (StringUtils.isBlank(namespaceURI)) { if (StringUtils.isBlank(namespaceURI)) {
namespaceURI = "http://www.w3.org/1999/xhtml"; namespaceURI = "http://www.w3.org/1999/xhtml";
} }
theEventWriter.writeStartElement(se.getName().getLocalPart());
theEventWriter.writeDefaultNamespace(namespaceURI); theEventWriter.writeDefaultNamespace(namespaceURI);
} else { } else {
theEventWriter.writeNamespace(se.getName().getPrefix(), se.getName().getNamespaceURI()); String prefix = se.getName().getPrefix();
String namespaceURI = se.getName().getNamespaceURI();
theEventWriter.writeStartElement(prefix, se.getName().getLocalPart(), namespaceURI);
theEventWriter.writeNamespace(prefix, namespaceURI);
} }
} else { } else {
if (isBlank(se.getName().getPrefix())) { if (isBlank(se.getName().getPrefix())) {

View File

@ -67,10 +67,10 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
set.add(Constants.PARAM_COUNT); set.add(Constants.PARAM_COUNT);
ALLOWED_PARAMS = Collections.unmodifiableSet(set); ALLOWED_PARAMS = Collections.unmodifiableSet(set);
} }
private MethodReturnTypeEnum myMethodReturnType; private MethodReturnTypeEnum myMethodReturnType;
private Class<?> myResourceListCollectionType; private Class<?> myResourceListCollectionType;
private String myResourceName; private String myResourceName;
private Class<? extends IResource> myResourceType; private Class<? extends IResource> myResourceType;
public BaseResourceReturningMethodBinding(Class<? extends IResource> theReturnResourceType, Method theMethod, FhirContext theConetxt, Object theProvider) { public BaseResourceReturningMethodBinding(Class<? extends IResource> theReturnResourceType, Method theMethod, FhirContext theConetxt, Object theProvider) {

View File

@ -27,6 +27,7 @@ import java.util.List;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome; import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
@ -55,60 +56,6 @@ public class FhirValidator {
setValidateAgainstStandardSchematron(true); setValidateAgainstStandardSchematron(true);
} }
/**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
* distribution itself)
*/
public boolean isValidateAgainstStandardSchema() {
return haveValidatorOfType(SchemaBaseValidator.class);
}
/**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
* distribution itself)
*/
public void setValidateAgainstStandardSchema(boolean theValidateAgainstStandardSchema) {
addOrRemoveValidator(theValidateAgainstStandardSchema, SchemaBaseValidator.class, new SchemaBaseValidator());
}
/**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
* distribution itself)
*/
public boolean isValidateAgainstStandardSchematron() {
return haveValidatorOfType(SchematronBaseValidator.class);
}
/**
* Should the validator validate the resource against the base schematron (the schematron provided with the FHIR
* distribution itself)
*/
public void setValidateAgainstStandardSchematron(boolean theValidateAgainstStandardSchematron) {
addOrRemoveValidator(theValidateAgainstStandardSchematron, SchematronBaseValidator.class, new SchematronBaseValidator());
}
/**
* Validates a resource instance, throwing a {@link ValidationFailureException} if the validation fails
*
* @param theResource The resource to validate
* @throws ValidationFailureException If the validation fails
*/
public void validate(IResource theResource) throws ValidationFailureException {
Validate.notNull(theResource, "theResource must not be null");
ValidationContext<IResource> ctx = ValidationContext.forResource(myContext, theResource);
for (IValidator next : myValidators) {
next.validateResource(ctx);
}
OperationOutcome oo = ctx.getOperationOutcome();
if (oo != null && oo.getIssue().size() > 0) {
throw new ValidationFailureException(oo.getIssueFirstRep().getDetails().getValue(), oo);
}
}
private void addOrRemoveValidator(boolean theValidateAgainstStandardSchema, Class<? extends IValidator> type, IValidator instance) { private void addOrRemoveValidator(boolean theValidateAgainstStandardSchema, Class<? extends IValidator> type, IValidator instance) {
if (theValidateAgainstStandardSchema) { if (theValidateAgainstStandardSchema) {
boolean found = haveValidatorOfType(type); boolean found = haveValidatorOfType(type);
@ -135,4 +82,81 @@ public class FhirValidator {
return found; return found;
} }
/**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
* distribution itself)
*/
public boolean isValidateAgainstStandardSchema() {
return haveValidatorOfType(SchemaBaseValidator.class);
}
/**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
* distribution itself)
*/
public boolean isValidateAgainstStandardSchematron() {
return haveValidatorOfType(SchematronBaseValidator.class);
}
/**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
* distribution itself)
*/
public void setValidateAgainstStandardSchema(boolean theValidateAgainstStandardSchema) {
addOrRemoveValidator(theValidateAgainstStandardSchema, SchemaBaseValidator.class, new SchemaBaseValidator());
}
/**
* Should the validator validate the resource against the base schematron (the schematron provided with the FHIR
* distribution itself)
*/
public void setValidateAgainstStandardSchematron(boolean theValidateAgainstStandardSchematron) {
addOrRemoveValidator(theValidateAgainstStandardSchematron, SchematronBaseValidator.class, new SchematronBaseValidator());
}
/**
* Validates a bundle instance, throwing a {@link ValidationFailureException} if the validation fails. This
* validation includes validation of all resources in the bundle.
*
* @param theResource The resource to validate
* @throws ValidationFailureException If the validation fails
*/
public void validate(Bundle theBundle) {
Validate.notNull(theBundle, "theBundle must not be null");
ValidationContext<Bundle> ctx = ValidationContext.forBundle(myContext, theBundle);
for (IValidator next : myValidators) {
next.validateBundle(ctx);
}
OperationOutcome oo = ctx.getOperationOutcome();
if (oo != null && oo.getIssue().size() > 0) {
throw new ValidationFailureException(oo);
}
}
/**
* Validates a resource instance, throwing a {@link ValidationFailureException} if the validation fails
*
* @param theResource The resource to validate
* @throws ValidationFailureException If the validation fails
*/
public void validate(IResource theResource) throws ValidationFailureException {
Validate.notNull(theResource, "theResource must not be null");
ValidationContext<IResource> ctx = ValidationContext.forResource(myContext, theResource);
for (IValidator next : myValidators) {
next.validateResource(ctx);
}
OperationOutcome oo = ctx.getOperationOutcome();
if (oo != null && oo.getIssue().size() > 0) {
throw new ValidationFailureException(oo);
}
}
} }

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.validation; package ca.uhn.fhir.validation;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
/* /*
@ -27,4 +28,6 @@ interface IValidator {
void validateResource(ValidationContext<IResource> theCtx); void validateResource(ValidationContext<IResource> theCtx);
void validateBundle(ValidationContext<Bundle> theContext);
} }

View File

@ -69,15 +69,6 @@ class SchemaBaseValidator implements IValidator {
private Map<String, Schema> myKeyToSchema = new HashMap<String, Schema>(); private Map<String, Schema> myKeyToSchema = new HashMap<String, Schema>();
public void validateBundle(ValidationContext<Bundle> theContext) {
doValidate(theContext, "fhir-atom-single.xsd");
}
@Override
public void validateResource(ValidationContext<IResource> theContext) {
doValidate(theContext, "fhir-single.xsd");
}
private void doValidate(ValidationContext<?> theContext, String schemaName) { private void doValidate(ValidationContext<?> theContext, String schemaName) {
Schema schema = loadSchema("dstu", schemaName); Schema schema = loadSchema("dstu", schemaName);
@ -128,6 +119,16 @@ class SchemaBaseValidator implements IValidator {
return baseSource; return baseSource;
} }
@Override
public void validateBundle(ValidationContext<Bundle> theContext) {
doValidate(theContext, "fhir-atom-single.xsd");
}
@Override
public void validateResource(ValidationContext<IResource> theContext) {
doValidate(theContext, "fhir-single.xsd");
}
private static class MyErrorHandler implements org.xml.sax.ErrorHandler { private static class MyErrorHandler implements org.xml.sax.ErrorHandler {
private ValidationContext<?> myContext; private ValidationContext<?> myContext;
@ -136,6 +137,13 @@ class SchemaBaseValidator implements IValidator {
myContext = theContext; myContext = theContext;
} }
private void addIssue(SAXParseException theException, IssueSeverityEnum severity) {
Issue issue = myContext.getOperationOutcome().addIssue();
issue.setSeverity(severity);
issue.setDetails(theException.getLocalizedMessage());
issue.addLocation().setValue("Line[" + theException.getLineNumber() + "] Col[" + theException.getColumnNumber() + "]");
}
@Override @Override
public void error(SAXParseException theException) throws SAXException { public void error(SAXParseException theException) throws SAXException {
addIssue(theException, IssueSeverityEnum.ERROR); addIssue(theException, IssueSeverityEnum.ERROR);
@ -151,13 +159,6 @@ class SchemaBaseValidator implements IValidator {
addIssue(theException, IssueSeverityEnum.WARNING); addIssue(theException, IssueSeverityEnum.WARNING);
} }
private void addIssue(SAXParseException theException, IssueSeverityEnum severity) {
Issue issue = myContext.getOperationOutcome().addIssue();
issue.setSeverity(severity);
issue.setDetails(theException.getLocalizedMessage());
issue.addLocation().setValue("Line[" + theException.getLineNumber() + "] Col[" + theException.getColumnNumber() + "]");
}
} }
private static final class MyResourceResolver implements LSResourceResolver { private static final class MyResourceResolver implements LSResourceResolver {

View File

@ -30,6 +30,8 @@ import javax.xml.transform.stream.StreamSource;
import org.oclc.purl.dsdl.svrl.SchematronOutputType; import org.oclc.purl.dsdl.svrl.SchematronOutputType;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome.Issue; import ca.uhn.fhir.model.dstu.resource.OperationOutcome.Issue;
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum; import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
@ -87,20 +89,22 @@ public class SchematronBaseValidator implements IValidator {
Class<? extends IResource> resource = theCtx.getResource().getClass(); Class<? extends IResource> resource = theCtx.getResource().getClass();
Class<? extends IResource> baseResourceClass = theCtx.getFhirContext().getResourceDefinition(resource).getBaseDefinition().getImplementingClass(); Class<? extends IResource> baseResourceClass = theCtx.getFhirContext().getResourceDefinition(resource).getBaseDefinition().getImplementingClass();
return getSchematronAndCache(theCtx, "dstu",baseResourceClass); return getSchematronAndCache(theCtx, "dstu", baseResourceClass);
} }
private ISchematronResource getSchematronAndCache(ValidationContext<IResource> theCtx, String theVersion , Class<? extends IResource> theClass) { private ISchematronResource getSchematronAndCache(ValidationContext<IResource> theCtx, String theVersion, Class<? extends IResource> theClass) {
synchronized (myClassToSchematron) { synchronized (myClassToSchematron) {
ISchematronResource retVal = myClassToSchematron.get(theClass); ISchematronResource retVal = myClassToSchematron.get(theClass);
if (retVal != null) { if (retVal != null) {
return retVal; return retVal;
} }
String pathToBase = "ca/uhn/fhir/model/"+theVersion+"/schema/" + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName().toLowerCase() + ".sch"; String pathToBase = "ca/uhn/fhir/model/" + theVersion + "/schema/" + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName().toLowerCase()
+ ".sch";
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase); InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
if (baseIs == null) { if (baseIs == null) {
throw new ValidationFailureException("No schematron found for resource type: " + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getImplementingClass().getCanonicalName()); throw new ValidationFailureException("No schematron found for resource type: "
+ theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getImplementingClass().getCanonicalName());
} }
retVal = SchematronResourceSCH.fromClassPath(pathToBase); retVal = SchematronResourceSCH.fromClassPath(pathToBase);
@ -109,4 +113,14 @@ public class SchematronBaseValidator implements IValidator {
} }
} }
@Override
public void validateBundle(ValidationContext<Bundle> theContext) {
for (BundleEntry next : theContext.getResource().getEntries()) {
if (next.getResource() != null) {
ValidationContext<IResource> ctx = ValidationContext.newChild(theContext, next.getResource());
validateResource(ctx);
}
}
}
} }

View File

@ -79,6 +79,12 @@ class ValidationContext<T> {
}); });
} }
public static ValidationContext<IResource> newChild(ValidationContext<Bundle> theContext, IResource theResource) {
ValidationContext<IResource> retVal = forResource(theContext.getFhirContext(), theResource);
retVal.myOperationOutcome = theContext.getOperationOutcome();
return retVal;
}
private interface IEncoder { private interface IEncoder {
String encode(); String encode();
} }

View File

@ -32,6 +32,14 @@ public class ValidationFailureException extends RuntimeException {
this(theProblem, IssueSeverityEnum.FATAL, null); this(theProblem, IssueSeverityEnum.FATAL, null);
} }
private static String toDescription(OperationOutcome theOo) {
StringBuilder b = new StringBuilder();
b.append(theOo.getIssueFirstRep().getDetails().getValue());
b.append(" - ");
b.append(theOo.getIssueFirstRep().getLocationFirstRep().getValue());
return b.toString();
}
public ValidationFailureException(String theProblem, Exception theCause) { public ValidationFailureException(String theProblem, Exception theCause) {
this(theProblem, IssueSeverityEnum.FATAL, theCause); this(theProblem, IssueSeverityEnum.FATAL, theCause);
} }
@ -42,8 +50,8 @@ public class ValidationFailureException extends RuntimeException {
myOperationOutcome.addIssue().setSeverity(theSeverity).setDetails(theProblem); myOperationOutcome.addIssue().setSeverity(theSeverity).setDetails(theProblem);
} }
public ValidationFailureException(String theProblem, OperationOutcome theOperationOutcome) { public ValidationFailureException(OperationOutcome theOperationOutcome) {
super(theProblem); super(toDescription(theOperationOutcome));
myOperationOutcome = theOperationOutcome; myOperationOutcome = theOperationOutcome;
} }

View File

@ -104,7 +104,7 @@
<p> <p>
To enable detailed logging of client requests and responses (what URL is being requested, what headers and payload To enable detailed logging of client requests and responses (what URL is being requested, what headers and payload
are being received, etc.), an interceptor may be added to the client which logs each transaction. See are being received, etc.), an interceptor may be added to the client which logs each transaction. See
<a href="./doc_rest_client.html#req_resp_logging">Logging Requests and Responses</a> for more information. <a href="./doc_rest_client_interceptor.html#req_resp_logging">Logging Requests and Responses</a> for more information.
</p> </p>
</section> </section>

View File

@ -11,6 +11,9 @@
<section name="Client Interceptors"> <section name="Client Interceptors">
<macro name="toc">
</macro>
<p> <p>
Both generic clients and annotation-driven clients support Both generic clients and annotation-driven clients support
<a href="./apidocs/ca/uhn/fhir/rest/client/IClientInterceptor.html">Client Interceptors</a>, <a href="./apidocs/ca/uhn/fhir/rest/client/IClientInterceptor.html">Client Interceptors</a>,

View File

@ -0,0 +1,81 @@
package ca.uhn.fhir.context;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
public class NameChanges {
@SuppressWarnings("unchecked")
@Test
public void testNameChanges() throws IOException, ClassNotFoundException {
FhirContext ctx = new FhirContext();
ImmutableSet<ClassInfo> names = ClassPath.from(getClass().getClassLoader()).getTopLevelClasses(Patient.class.getPackage().getName());
List<String> changes = new ArrayList<String>();
for (ClassInfo classInfo : names) {
RuntimeResourceDefinition def = ctx.getResourceDefinition((Class<? extends IResource>) Class.forName(classInfo.getName()));
for (RuntimeSearchParam nextParam : def.getSearchParams()) {
if (nextParam.getParamType() == SearchParamTypeEnum.COMPOSITE) {
continue;
}
String name = nextParam.getName();
if (name.contains("[x]")) {
continue;
}
if (name.startsWith("_")) {
continue; // _id and _language
}
String path = nextParam.getPath();
if (path.contains(" | ")) {
changes.add(def.getName() + ": " + name + " has multiple paths so there is no obvious name (" + nextParam.getDescription() + ")");
continue;
}
path = path.substring(path.indexOf('.') + 1);
StringBuilder b = new StringBuilder();
for (int i = 0; i < path.length(); i++) {
char nextChar = path.charAt(i);
if (Character.isUpperCase(nextChar)) {
b.append('-');
}else if (nextChar == '.') {
b.append('-');
continue;
}
b.append(Character.toLowerCase(nextChar));
}
if (name.equals(b.toString())==false) {
changes.add(def.getName() + "," + name + "," + b + "," + nextParam.getDescription());
}
}
}
System.out.println("Resource,old name,new name,description");
for (String next : changes) {
System.out.println(next);
}
}
}

View File

@ -1,9 +1,17 @@
package ca.uhn.fhir.parser; package ca.uhn.fhir.parser;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*; import static org.hamcrest.Matchers.not;
import static org.mockito.Matchers.*; import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.mockito.Mockito.*; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
@ -28,7 +36,6 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
@ -63,6 +70,31 @@ public class JsonParserTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserTest.class);
private static FhirContext ourCtx; private static FhirContext ourCtx;
@Test
public void testEncodeNarrativeBlockInBundle() {
Patient p = new Patient();
p.addIdentifier("foo", "bar");
p.getText().setStatus(NarrativeStatusEnum.GENERATED);
p.getText().setDiv("<div>hello</div>");
Bundle b = new Bundle();
b.getTotalResults().setValue(123);
b.addEntry().setResource(p);
String out = ourCtx.newJsonParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(out);
assertThat(out, containsString("<div>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);
ourLog.info(out);
// Backslashes need to be escaped because they are in a JSON value
assertThat(out, containsString("<xhtml:div xmlns:xhtml=\\\"http://www.w3.org/1999/xhtml\\\">hello</xhtml:div>"));
}
@Test @Test
public void testEncodingNullExtension() { public void testEncodingNullExtension() {
Patient p = new Patient(); Patient p = new Patient();

View File

@ -282,6 +282,29 @@ public class XmlParserTest {
} }
} }
@Test
public void testEncodeNarrativeBlockInBundle() {
Patient p = new Patient();
p.addIdentifier("foo", "bar");
p.getText().setStatus(NarrativeStatusEnum.GENERATED);
p.getText().setDiv("<div>hello</div>");
Bundle b = new Bundle();
b.getTotalResults().setValue(123);
b.addEntry().setResource(p);
String out = ourCtx.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(out);
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.newXmlParser().setPrettyPrint(true).encodeBundleToString(b);
ourLog.info(out);
assertThat(out, containsString("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">hello</xhtml:div>"));
}
@Test @Test
public void testEncodePrettyPrint() throws DataFormatException { public void testEncodePrettyPrint() throws DataFormatException {

View File

@ -9,6 +9,7 @@ import org.apache.commons.io.IOUtils;
import org.junit.Test; import org.junit.Test;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.resource.Patient; import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum; import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
@ -18,7 +19,7 @@ public class ResourceValidatorTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidatorTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidatorTest.class);
@Test @Test
public void testSchemaValidator() throws IOException { public void testSchemaResourceValidator() throws IOException {
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml")); String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml"));
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res); Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res);
@ -39,12 +40,33 @@ public class ResourceValidatorTest {
} }
} }
@Test
public void testSchemaBundleValidator() throws IOException {
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("atom-document-large.xml"));
Bundle b = ourCtx.newXmlParser().parseBundle(res);
FhirValidator val = ourCtx.newValidator();
val.setValidateAgainstStandardSchema(true);
val.setValidateAgainstStandardSchematron(false);
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(false).encodeBundleToString(b).substring(15600));
val.validate(b);
// b.getAnimal().getBreed().setText("The Breed");
// try {
// val.validate(b);
// fail();
// } catch (ValidationFailureException e) {
// ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
// assertEquals(1, e.getOperationOutcome().getIssue().size());
// assertThat(e.getOperationOutcome().getIssueFirstRep().getDetails().getValue(), containsString("Invalid content was found starting with element 'breed'"));
// }
}
@Test @Test
public void testSchematronValidator() throws IOException { public void testSchematronResourceValidator() throws IOException {
// System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl ");
// System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml")); String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml"));
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res); Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res);

View File

@ -216,6 +216,7 @@
<Patient id="cid:b01227b1-2701-4f9f-93b3-428146aa3ed3" xmlns="http://hl7.org/fhir"> <Patient id="cid:b01227b1-2701-4f9f-93b3-428146aa3ed3" xmlns="http://hl7.org/fhir">
<language value="en-US" /> <language value="en-US" />
<text> <text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div> <div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text> </text>
<identifier> <identifier>
@ -262,6 +263,7 @@
<Patient id="cid:dd85a42b-eab0-4863-b4e4-2296e8369e9a" xmlns="http://hl7.org/fhir"> <Patient id="cid:dd85a42b-eab0-4863-b4e4-2296e8369e9a" xmlns="http://hl7.org/fhir">
<language value="en-US" /> <language value="en-US" />
<text> <text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div> <div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text> </text>
<identifier> <identifier>
@ -339,6 +341,7 @@
<Patient xmlns="http://hl7.org/fhir"> <Patient xmlns="http://hl7.org/fhir">
<language value="en-US" /> <language value="en-US" />
<text> <text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div> <div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text> </text>
<identifier> <identifier>
@ -385,6 +388,7 @@
<Patient xmlns="http://hl7.org/fhir"> <Patient xmlns="http://hl7.org/fhir">
<language value="en-US" /> <language value="en-US" />
<text> <text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div> <div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text> </text>
<identifier> <identifier>
@ -431,6 +435,7 @@
<Patient xmlns="http://hl7.org/fhir"> <Patient xmlns="http://hl7.org/fhir">
<language value="en-US" /> <language value="en-US" />
<text> <text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div> <div xmlns="http://www.w3.org/1999/xhtml">Parkerson, Parkie</div>
</text> </text>
<identifier> <identifier>

View File

@ -12,7 +12,7 @@
<dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base"> <dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type> <dependency-type>uses</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.6-SNAPSHOT/hapi-fhir-testpage-overlay-0.6-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependency-type>consumes</dependency-type> <dependency-type>consumes</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">

11
pom.xml
View File

@ -22,6 +22,17 @@
<inceptionYear>2014</inceptionYear> <inceptionYear>2014</inceptionYear>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/jamesagnew/hapi-fhir/issues/</url>
</issueManagement>
<scm>
<connection>scm:git:git@github.com:jamesagnew/hapi-fhir.git</connection>
<url>scm:git:git@github.com:jamesagnew/hapi-fhir.git</url>
<developerConnection>scm:git:git@github.com:jamesagnew/hapi-fhir.git</developerConnection>
</scm>
<description> <description>
</description> </description>

View File

@ -6,7 +6,7 @@
<dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base"> <dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type> <dependency-type>uses</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.6-SNAPSHOT/hapi-fhir-testpage-overlay-0.6-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependency-type>consumes</dependency-type> <dependency-type>consumes</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">

View File

@ -92,6 +92,12 @@
<build> <build>
<!--
Tells Maven to name the generated WAR file as
restful-server-example.war
-->
<finalName>restful-server-example</finalName>
<!-- <!--
The following is not required for the application to build, but The following is not required for the application to build, but
allows you to test it by issuing "mvn jetty:run" from the command allows you to test it by issuing "mvn jetty:run" from the command