Handle unexpected extensions when parsing using IParserErrorHandler
This commit is contained in:
parent
4573b86972
commit
3fd9f9518a
|
@ -867,7 +867,7 @@ class ParserState<T> {
|
|||
ParserState<T>.ExtensionState newState = new ExtensionState(myPreResourceState, ext);
|
||||
push(newState);
|
||||
} else {
|
||||
throw new DataFormatException("Type " + getCurrentElement() + " does not support undeclared extentions, and found an extension with URL: " + theUrlAttr);
|
||||
logAndSwallowUnexpectedElement("extension");
|
||||
}
|
||||
} else {
|
||||
if (getCurrentElement() instanceof IBaseHasModifierExtensions) {
|
||||
|
@ -876,7 +876,7 @@ class ParserState<T> {
|
|||
ParserState<T>.ExtensionState newState = new ExtensionState(myPreResourceState, ext);
|
||||
push(newState);
|
||||
} else {
|
||||
throw new DataFormatException("Type " + getCurrentElement() + " does not support undeclared extentions, and found an extension with URL: " + theUrlAttr);
|
||||
logAndSwallowUnexpectedElement("modifierExtension");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,24 @@ public class ElementUtil {
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
public static <T> void validateAllElementsAreOfTypeOrThrowClassCastExceptionForModelSetter(List<T> theList, Class<T> theType) {
|
||||
if (theList == null) {
|
||||
return;
|
||||
}
|
||||
for (T next : theList) {
|
||||
if (next != null && theType.isAssignableFrom(next.getClass()) == false) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("Failed to set invalid value, found element in list of type ");
|
||||
b.append(next.getClass().getSimpleName());
|
||||
b.append(" but expected ");
|
||||
b.append(theType.getName());
|
||||
throw new ClassCastException(b.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public static boolean isEmpty(List<? extends IBase> theElements) {
|
||||
if (theElements == null) {
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package ca.uhn.fhir.model.dstu2;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
|
||||
public class ModelDstu2Test {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||
|
||||
/**
|
||||
* See #304
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Test
|
||||
public void testPopulateWrongGenericType() {
|
||||
Patient p = new Patient();
|
||||
List names = Arrays.asList("name");
|
||||
|
||||
p.setName(null);
|
||||
|
||||
ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
|
||||
try {
|
||||
p.setName(names);
|
||||
fail();
|
||||
} catch (ClassCastException e) {
|
||||
assertEquals("Failed to set invalid value, found element in list of type String but expected ca.uhn.fhir.model.dstu2.composite.HumanNameDt", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,7 +2,6 @@ package ca.uhn.fhir.parser;
|
|||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.emptyString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -11,6 +10,9 @@ import static org.junit.Assert.assertNull;
|
|||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -21,6 +23,8 @@ import org.apache.commons.io.IOUtils;
|
|||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
@ -56,6 +60,7 @@ import ca.uhn.fhir.model.primitive.DateTimeDt;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.IParserErrorHandler.IParseLocation;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import net.sf.json.JSON;
|
||||
import net.sf.json.JSONSerializer;
|
||||
|
@ -109,10 +114,8 @@ public class JsonParserDstu2Test {
|
|||
assertThat(enc, Matchers.stringContainsInOrder("{\"resourceType\":\"Patient\",", "\"extension\":[{\"url\":\"http://example.com/extensions#someext\",\"valueDateTime\":\"2011-01-02T11:13:15\"}",
|
||||
"{\"url\":\"http://example.com#parent\",\"extension\":[{\"url\":\"http://example.com#child\",\"valueString\":\"value1\"},{\"url\":\"http://example.com#child\",\"valueString\":\"value2\"}]}"));
|
||||
assertThat(enc, Matchers.stringContainsInOrder("\"modifierExtension\":[" + "{" + "\"url\":\"http://example.com/extensions#modext\"," + "\"valueDate\":\"1995-01-02\"" + "}" + "],"));
|
||||
assertThat(enc,
|
||||
containsString("\"_given\":[" + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext\"," + "\"valueString\":\"given\"" + "}" + "]" + "}," + "{" + "\"extension\":[" + "{"
|
||||
+ "\"url\":\"http://examples.com#givenext_parent\"," + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext_child\"," + "\"valueString\":\"CHILD\"" + "}" + "]" + "}"
|
||||
+ "]" + "}"));
|
||||
assertThat(enc, containsString("\"_given\":[" + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext\"," + "\"valueString\":\"given\"" + "}" + "]" + "}," + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext_parent\"," + "\"extension\":[" + "{"
|
||||
+ "\"url\":\"http://examples.com#givenext_child\"," + "\"valueString\":\"CHILD\"" + "}" + "]" + "}" + "]" + "}"));
|
||||
|
||||
/*
|
||||
* Now parse this back
|
||||
|
@ -207,7 +210,7 @@ public class JsonParserDstu2Test {
|
|||
assertEquals(new Tag("scheme1", "term1", "label1"), tagList.get(0));
|
||||
assertEquals(new Tag("scheme2", "term2", "label2"), tagList.get(1));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeAndParseSecurityLabels() {
|
||||
Patient p = new Patient();
|
||||
|
@ -333,7 +336,7 @@ public class JsonParserDstu2Test {
|
|||
Patient p = new Patient();
|
||||
p.setId(new IdDt("urn:uuid:42795ed8-041f-4ebf-b6f4-78ef6f64c2f2"));
|
||||
p.addIdentifier().setSystem("ACME");
|
||||
|
||||
|
||||
String actual = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
|
||||
assertThat(actual, not(containsString("78ef6f64c2f2")));
|
||||
}
|
||||
|
@ -431,8 +434,7 @@ public class JsonParserDstu2Test {
|
|||
ourLog.info(encoded);
|
||||
|
||||
assertThat(encoded, containsString("Patient"));
|
||||
assertThat(encoded, stringContainsInOrder("\"tag\"", "\"system\":\"foo\",", "\"code\":\"bar\"", "\"system\":\"" + Constants.TAG_SUBSETTED_SYSTEM + "\",",
|
||||
"\"code\":\"" + Constants.TAG_SUBSETTED_CODE + "\","));
|
||||
assertThat(encoded, stringContainsInOrder("\"tag\"", "\"system\":\"foo\",", "\"code\":\"bar\"", "\"system\":\"" + Constants.TAG_SUBSETTED_SYSTEM + "\",", "\"code\":\"" + Constants.TAG_SUBSETTED_CODE + "\","));
|
||||
assertThat(encoded, not(containsString("THE DIV")));
|
||||
assertThat(encoded, containsString("family"));
|
||||
assertThat(encoded, not(containsString("maritalStatus")));
|
||||
|
@ -453,8 +455,7 @@ public class JsonParserDstu2Test {
|
|||
String enc = ourCtx.newJsonParser().encodeResourceToString(pt);
|
||||
ourLog.info(enc);
|
||||
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"meta\":{\"tag\":[{\"system\":\"scheme\",\"code\":\"term\",\"display\":\"display\"}]},\"identifier\":[{\"system\":\"sys\",\"value\":\"val\"}]}",
|
||||
enc);
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"meta\":{\"tag\":[{\"system\":\"scheme\",\"code\":\"term\",\"display\":\"display\"}]},\"identifier\":[{\"system\":\"sys\",\"value\":\"val\"}]}", enc);
|
||||
|
||||
}
|
||||
|
||||
|
@ -537,11 +538,11 @@ public class JsonParserDstu2Test {
|
|||
public void testNamespacePreservationParse() throws Exception {
|
||||
String input = "{\"resourceType\":\"Patient\",\"text\":{\"div\":\"<xhtml:div xmlns:xhtml=\\\"http://www.w3.org/1999/xhtml\\\"><xhtml:img src=\\\"foo\\\"/>@fhirabend</xhtml:div>\"}}";
|
||||
Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, input);
|
||||
|
||||
|
||||
assertEquals("<xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"><xhtml:img src=\"foo\"/>@fhirabend</xhtml:div>", parsed.getText().getDiv().getValueAsString());
|
||||
|
||||
|
||||
String encoded = ourCtx.newXmlParser().encodeResourceToString(parsed);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><text><xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"><xhtml:img src=\"foo\"/>@fhirabend</xhtml:div></text></Patient>",encoded);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><text><xhtml:div xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"><xhtml:img src=\"foo\"/>@fhirabend</xhtml:div></text></Patient>", encoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1067,6 +1068,30 @@ public class JsonParserDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseWithExtensions() throws Exception {
|
||||
String input = IOUtils.toString(getClass().getResourceAsStream("/patient1.json"));
|
||||
IParser parser = ourCtx.newJsonParser();
|
||||
IParserErrorHandler peh = mock(IParserErrorHandler.class);
|
||||
parser.setParserErrorHandler(peh);
|
||||
Patient p = parser.parseResource(Patient.class, input);
|
||||
|
||||
ArgumentCaptor<String> capt = ArgumentCaptor.forClass(String.class);
|
||||
verify(peh, times(4)).unknownElement(Mockito.isNull(IParseLocation.class), capt.capture());
|
||||
|
||||
//@formatter:off
|
||||
List<String> strings = capt.getAllValues();
|
||||
assertThat(strings, contains(
|
||||
"extension",
|
||||
"extension",
|
||||
"modifierExtension",
|
||||
"modifierExtension"
|
||||
));
|
||||
//@formatter:off
|
||||
|
||||
assertEquals("Smith", p.getName().get(0).getGiven().get(0).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseWithWrongTypeObjectShouldBeArray() throws Exception {
|
||||
String input = IOUtils.toString(getClass().getResourceAsStream("/invalid_metadata.json"));
|
||||
|
|
|
@ -97,6 +97,7 @@ public class XmlParserDstu2Test {
|
|||
private static final FhirContext ourCtx = FhirContext.forDstu2();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserDstu2Test.class);
|
||||
|
||||
|
||||
@Test
|
||||
public void testBundleWithBinary() {
|
||||
//@formatter:off
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"id": "73b551fb-46f5-4fb8-b735-2399344e9717",
|
||||
"meta": {
|
||||
"extension": [
|
||||
{
|
||||
"url": "fhir-request-method",
|
||||
"valueString": "POST"
|
||||
},
|
||||
{
|
||||
"url": "fhir-request-uri",
|
||||
"valueUri": "Patient"
|
||||
}
|
||||
],
|
||||
"modifierExtension": [
|
||||
{
|
||||
"url": "fhir-request-method",
|
||||
"valueString": "POST"
|
||||
},
|
||||
{
|
||||
"url": "fhir-request-uri",
|
||||
"valueUri": "Patient"
|
||||
}
|
||||
],
|
||||
"versionId": "01e5253d-d258-494c-8d8e-f22ad6d8f19b",
|
||||
"lastUpdated": "2016-02-20T11:01:56.155Z"
|
||||
},
|
||||
"name": [
|
||||
{
|
||||
"given": [
|
||||
"Smith"
|
||||
]
|
||||
}
|
||||
],
|
||||
"resourceType": "Patient"
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package ca.uhn.fhir.model;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ModelDstu3Test {
|
||||
|
||||
/**
|
||||
* See #304
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Test
|
||||
public void testPopulateWrongGenericType() {
|
||||
Patient p = new Patient();
|
||||
List names = Arrays.asList("name");
|
||||
|
||||
p.setName(null);
|
||||
try {
|
||||
p.setName(names);
|
||||
fail();
|
||||
} catch (ClassCastException e) {
|
||||
assertEquals("Failed to set invalid value, found element in list of type String but expected ca.uhn.fhir.model.dstu2.composite.HumanNameDt", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -123,7 +123,9 @@ public abstract class Child extends BaseElement {
|
|||
public String getSingleType() {
|
||||
String retVal;
|
||||
String elemName = this.getType().get(0);
|
||||
elemName = elemName.substring(0, 1).toUpperCase() + elemName.substring(1);
|
||||
if (elemName.startsWith("ca.") == false) {
|
||||
elemName = elemName.substring(0, 1).toUpperCase() + elemName.substring(1);
|
||||
}
|
||||
// if (this instanceof ResourceBlock) {
|
||||
retVal = (elemName);
|
||||
// } else {
|
||||
|
|
|
@ -158,6 +158,12 @@
|
|||
buttom will no longer show a "loading" spinner, but there doesn't seem to
|
||||
be another way of fixing this. Thanks to Mark Scrimshire for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Extensions found while parsing an object that doesn't support extensions are now
|
||||
reported using the IParserErrorHandler framework in the same way that
|
||||
other similar errors are handled. This allows the parser to be more lenient
|
||||
when needed.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.4" date="2016-02-04">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue