Fix #344 - make getResourceDefinition(String) and getElementDefnition(String) case insensitive

This commit is contained in:
jamesagnew 2016-04-25 07:19:31 -04:00
parent c48a5224b4
commit 3fce4cb087
6 changed files with 131 additions and 40 deletions

View File

@ -27,10 +27,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -185,9 +183,12 @@ public class FhirContext {
/**
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed
* for extending the core library.
* <p>
* Note that this method is case insensitive!
* </p>
*/
public BaseRuntimeElementDefinition<?> getElementDefinition(String theElementName) {
return myNameToElementDefinition.get(theElementName);
return myNameToElementDefinition.get(theElementName.toLowerCase());
}
/** For unit tests only */
@ -275,23 +276,15 @@ public class FhirContext {
/**
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed
* for extending the core library.
* <p>
* Note that this method is case insensitive!
* </p>
*/
@SuppressWarnings("unchecked")
public RuntimeResourceDefinition getResourceDefinition(String theResourceName) {
Validate.notBlank(theResourceName, "theResourceName must not be blank");
String resourceName = theResourceName;
/*
* TODO: this is a bit of a hack, really we should have a translation table based on a property file or
* something so that we can detect names like diagnosticreport
*/
if (Character.isLowerCase(resourceName.charAt(0))) {
resourceName = WordUtils.capitalize(resourceName);
}
Validate.notBlank(resourceName, "Resource name must not be blank");
String resourceName = theResourceName.toLowerCase();
RuntimeResourceDefinition retVal = myNameToResourceDefinition.get(resourceName);
if (retVal == null) {

View File

@ -319,7 +319,7 @@ class ModelScanner {
resourceDef = new RuntimeCompositeDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
}
myClassToElementDefinitions.put(theClass, resourceDef);
myNameToElementDefinitions.put(resourceDef.getName(), resourceDef);
myNameToElementDefinitions.put(resourceDef.getName().toLowerCase(), resourceDef);
scanCompositeElementForChildren(theClass, resourceDef);
}
@ -709,7 +709,7 @@ class ModelScanner {
myClassToElementDefinitions.put(theClass, resourceDef);
if (primaryNameProvider) {
if (resourceDef.getStructureVersion() == myVersion) {
myNameToResourceDefinitions.put(resourceName, resourceDef);
myNameToResourceDefinitions.put(resourceName.toLowerCase(), resourceDef);
}
}
scanCompositeElementForChildren(theClass, resourceDef);

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.parser;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
@ -2090,6 +2091,9 @@ class ParserState<T> {
}
RuntimeResourceDefinition def = (RuntimeResourceDefinition) definition;
if (!definition.getName().equals(theLocalPart) && definition.getName().equalsIgnoreCase(theLocalPart)) {
throw new DataFormatException("Unknown resource type '" + theLocalPart + "': Resource names are case sensitive, found similar name: '" + definition.getName() + "'");
}
myInstance = def.newInstance();
String resourceName = def.getName();

View File

@ -4,6 +4,8 @@ import static org.junit.Assert.assertEquals;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.junit.AfterClass;
import org.junit.Test;
@ -22,7 +24,28 @@ public class FhirContextDstu3Test {
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
/**
* See #344
*/
@Test
public void testGetElementDefinitionCaseInsensitive() {
assertEquals(Reference.class, ourCtx.getElementDefinition("reference").getImplementingClass());
assertEquals(Reference.class, ourCtx.getElementDefinition("Reference").getImplementingClass());
assertEquals(Reference.class, ourCtx.getElementDefinition("REFerence").getImplementingClass());
}
/**
* See #344
*/
@Test
public void testGetResourceDefinitionCaseInsensitive() {
assertEquals(Patient.class, ourCtx.getResourceDefinition("patient").getImplementingClass());
assertEquals(Patient.class, ourCtx.getResourceDefinition("Patient").getImplementingClass());
assertEquals(Patient.class, ourCtx.getResourceDefinition("PATient").getImplementingClass());
assertEquals(StructureDefinition.class, ourCtx.getResourceDefinition("structuredefinition").getImplementingClass());
}
@Test
public void testCustomTypeDoesntBecomeDefault() {
FhirContext ctx = FhirContext.forDstu3();

View File

@ -57,6 +57,8 @@ import org.hl7.fhir.dstu3.model.PrimitiveType;
import org.hl7.fhir.dstu3.model.Quantity;
import org.hl7.fhir.dstu3.model.QuestionnaireResponse;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.SampledData;
import org.hl7.fhir.dstu3.model.SimpleQuantity;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.Type;
import org.hl7.fhir.dstu3.model.UriType;
@ -86,6 +88,41 @@ public class JsonParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
/**
* See #344
*/
@Test
public void testParserIsCaseSensitive() {
Observation obs = new Observation();
SampledData data = new SampledData();
data.setData("1 2 3");
data.setOrigin((SimpleQuantity) new SimpleQuantity().setValue(0L));
data.setPeriod(1000L);
obs.setValue(data);
IParser p = ourCtx.newJsonParser().setPrettyPrint(true).setParserErrorHandler(new StrictErrorHandler());
String encoded = p.encodeResourceToString(obs);
ourLog.info(encoded);
p.parseResource(encoded);
try {
p.parseResource(encoded.replace("Observation", "observation"));
fail();
} catch (DataFormatException e) {
assertEquals("Unknown resource type 'observation': Resource names are case sensitive, found similar name: 'Observation'", e.getMessage());
}
try {
p.parseResource(encoded.replace("valueSampledData", "valueSampleddata"));
fail();
} catch (DataFormatException e) {
assertEquals("Unknown element 'valueSampleddata' found during parse", e.getMessage());
}
}
@Test
public void testEncodeAndParseExtensions() throws Exception {

View File

@ -82,6 +82,7 @@ import org.hl7.fhir.dstu3.model.PrimitiveType;
import org.hl7.fhir.dstu3.model.Quantity;
import org.hl7.fhir.dstu3.model.Reference;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.dstu3.model.SampledData;
import org.hl7.fhir.dstu3.model.SimpleQuantity;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
@ -114,27 +115,10 @@ public class XmlParserDstu3Test {
ourCtx.setNarrativeGenerator(null);
}
/**
* See #347
*/
@Test
public void testEncodeAndParseMedicationOrder() {
MedicationOrder mo = new MedicationOrder();
mo.getDateWrittenElement().setValueAsString("2015-10-05");
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(mo);
ourLog.info(encoded);
mo = ourCtx.newXmlParser().parseResource(MedicationOrder.class, encoded);
assertEquals("2015-10-05", mo.getDateWrittenElement().getValueAsString());
}
@Test
public void testBundleWithBinary() {
//@formatter:off
String bundle = "<Bundle xmlns=\"http://hl7.org/fhir\">\n" +
" <meta/>\n" +
" <base value=\"http://localhost:52788\"/>\n" +
" <total value=\"1\"/>\n" +
" <link>\n" +
@ -184,6 +168,8 @@ public class XmlParserDstu3Test {
assertEquals("ORG", o.getName());
}
@Test
public void testDuration() {
Encounter enc = new Encounter();
@ -197,7 +183,7 @@ public class XmlParserDstu3Test {
assertThat(str, not(containsString("meta")));
assertThat(str, containsString("<length><value value=\"123\"/><unit value=\"day\"/></length>"));
}
@Test
public void testEncodeAndParseBundleWithResourceRefs() {
@ -234,7 +220,7 @@ public class XmlParserDstu3Test {
assertEquals("Organization/orgid", pt.getManagingOrganization().getReferenceElement().getValue());
assertSame(org, pt.getManagingOrganization().getResource());
}
@Test
public void testEncodeAndParseContained() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
@ -463,6 +449,21 @@ public class XmlParserDstu3Test {
assertEquals("MR", patient.getIdentifier().get(0).getType().getCoding().get(0).getCode());
}
/**
* See #347
*/
@Test
public void testEncodeAndParseMedicationOrder() {
MedicationOrder mo = new MedicationOrder();
mo.getDateWrittenElement().setValueAsString("2015-10-05");
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(mo);
ourLog.info(encoded);
mo = ourCtx.newXmlParser().parseResource(MedicationOrder.class, encoded);
assertEquals("2015-10-05", mo.getDateWrittenElement().getValueAsString());
}
@Test
public void testEncodeAndParseMetaProfileAndTags() {
Patient p = new Patient();
@ -1213,8 +1214,6 @@ public class XmlParserDstu3Test {
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://hello.world\"><valueString value=\"Hello World\"/></extension></Patient>", xml);
}
@Test
public void testEncodeReferenceUsingUnqualifiedResourceWorksCorrectly() {
@ -1252,6 +1251,8 @@ public class XmlParserDstu3Test {
assertThat(str, containsString("<reference value=\"Observation/phitcc_obs_bp_dia\"/>"));
}
@Test
public void testEncodeSummary() {
Patient patient = new Patient();
@ -1290,7 +1291,7 @@ public class XmlParserDstu3Test {
assertThat(encoded, containsString("family"));
assertThat(encoded, not(containsString("maritalStatus")));
}
@Test
public void testEncodeUndeclaredExtensionWithEnumerationContent() {
IParser parser = ourCtx.newXmlParser();
@ -1311,7 +1312,7 @@ public class XmlParserDstu3Test {
assertEquals("home", ref.getValue().toCode());
}
@Test
public void testEncodeWithContained() {
List<Resource> contained = new ArrayList<Resource>();
@ -2559,6 +2560,39 @@ public class XmlParserDstu3Test {
assertEquals("Patient", reincarnatedPatient.getIdElement().getResourceType());
}
/**
* See #344
*/
@Test
public void testParserIsCaseSensitive() {
Observation obs = new Observation();
SampledData data = new SampledData();
data.setData("1 2 3");
data.setOrigin((SimpleQuantity) new SimpleQuantity().setValue(0L));
data.setPeriod(1000L);
obs.setValue(data);
IParser p = ourCtx.newXmlParser().setPrettyPrint(true).setParserErrorHandler(new StrictErrorHandler());
String encoded = p.encodeResourceToString(obs);
ourLog.info(encoded);
p.parseResource(encoded);
try {
p.parseResource(encoded.replace("Observation", "observation"));
fail();
} catch (DataFormatException e) {
assertEquals("DataFormatException at [[row,col {unknown-source}]: [1,1]]: Unknown resource type 'observation': Resource names are case sensitive, found similar name: 'Observation'", e.getMessage());
}
try {
p.parseResource(encoded.replace("valueSampledData", "valueSampleddata"));
fail();
} catch (DataFormatException e) {
assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Unknown element 'valueSampleddata' found during parse", e.getMessage());
}
}
/**
* See #339
*