Skip to content

Commit

Permalink
Merge branch 'master' of github.com:jamesagnew/hapi-fhir
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesagnew committed Aug 25, 2016
2 parents 17940b8 + 3c65b64 commit a1105fa
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public enum FhirVersionEnum {

DSTU2_HL7ORG("org.hl7.fhir.instance.FhirDstu2Hl7Org", DSTU2, true, "1.0.2"),

DSTU3("org.hl7.fhir.dstu3.hapi.ctx.FhirDstu3", null, true, "1.5.0");
DSTU3("org.hl7.fhir.dstu3.hapi.ctx.FhirDstu3", null, true, "1.6.0");

private final FhirVersionEnum myEquivalent;
private final String myFhirVersionString;
Expand Down
96 changes: 46 additions & 50 deletions hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -105,6 +105,7 @@ class ParserState<T> {
private final IParser myParser;
private IBase myPreviousElement;
private BaseState myState;

private ParserState(IParser theParser, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) {
myParser = theParser;
myContext = theContext;
Expand Down Expand Up @@ -223,7 +224,8 @@ public void xmlEvent(XMLEvent theNextEvent) {
}
}

static ParserState<Bundle> getPreAtomInstance(IParser theParser, FhirContext theContext, Class<? extends IBaseResource> theResourceType, boolean theJsonMode, IParserErrorHandler theErrorHandler) throws DataFormatException {
static ParserState<Bundle> getPreAtomInstance(IParser theParser, FhirContext theContext, Class<? extends IBaseResource> theResourceType, boolean theJsonMode, IParserErrorHandler theErrorHandler)
throws DataFormatException {
ParserState<Bundle> retVal = new ParserState<Bundle>(theParser, theContext, theJsonMode, theErrorHandler);
if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
retVal.push(retVal.new PreAtomState(theResourceType));
Expand All @@ -237,7 +239,8 @@ static ParserState<Bundle> getPreAtomInstance(IParser theParser, FhirContext the
* @param theResourceType
* May be null
*/
static <T extends IBaseResource> ParserState<T> getPreResourceInstance(IParser theParser, Class<T> theResourceType, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) throws DataFormatException {
static <T extends IBaseResource> ParserState<T> getPreResourceInstance(IParser theParser, Class<T> theResourceType, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler)
throws DataFormatException {
ParserState<T> retVal = new ParserState<T>(theParser, theContext, theJsonMode, theErrorHandler);
if (theResourceType == null) {
if (theContext.getVersion().getVersion().isRi()) {
Expand Down Expand Up @@ -1389,7 +1392,7 @@ protected void populateTarget() {
@Override
public void wereBack() {
super.wereBack();

IResource res = (IResource) getCurrentElement();
assert res != null;
if (res.getId() == null || res.getId().isEmpty()) {
Expand Down Expand Up @@ -1582,7 +1585,7 @@ public void enteringNewElement(String theNamespace, String theChildName) throws
return;
}
}

/*
* This means we've found an element that doesn't exist on the structure. If the error handler doesn't throw
* an exception, swallow the element silently along with any child elements
Expand Down Expand Up @@ -1742,10 +1745,10 @@ public void attributeValue(String theName, String theValue) throws DataFormatExc
}
if ("id".equals(theName)) {
if (getCurrentElement() instanceof IBaseElement) {
((IBaseElement)getCurrentElement()).setId(theValue);
((IBaseElement) getCurrentElement()).setId(theValue);
return;
} else if (getCurrentElement() instanceof IIdentifiableElement) {
((IIdentifiableElement)getCurrentElement()).setElementSpecificId(theValue);
((IIdentifiableElement) getCurrentElement()).setElementSpecificId(theValue);
return;
}
}
Expand Down Expand Up @@ -1773,42 +1776,35 @@ public void enteringNewElement(String theNamespaceUri, String theLocalPart) thro
}

BaseRuntimeElementDefinition<?> target = myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(theLocalPart);
if (target == null) {
myErrorHandler.unknownElement(null, theLocalPart);
push(new SwallowChildrenWholeState(getPreResourceState()));
return;

if (target != null) {
switch (target.getChildType()) {
case COMPOSITE_DATATYPE: {
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance();
myExtension.setValue(newChildInstance);
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
push(newState);
return;
}
case ID_DATATYPE:
case PRIMITIVE_DATATYPE: {
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
myExtension.setValue(newChildInstance);
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
push(newState);
return;
}
}
}

switch (target.getChildType()) {
case COMPOSITE_DATATYPE: {
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance();
myExtension.setValue(newChildInstance);
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
push(newState);
return;
}
case PRIMITIVE_DATATYPE: {
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
myExtension.setValue(newChildInstance);
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
push(newState);
return;
}
case PRIMITIVE_XHTML:
case RESOURCE:
case RESOURCE_BLOCK:
case UNDECL_EXT:
case EXTENSION_DECLARED:
case CONTAINED_RESOURCES:
case CONTAINED_RESOURCE_LIST:
case ID_DATATYPE:
case PRIMITIVE_XHTML_HL7ORG:
break;
}
// We hit an invalid type for the extension
myErrorHandler.unknownElement(null, theLocalPart);
push(new SwallowChildrenWholeState(getPreResourceState()));
return;
}

@Override
protected IBaseExtension<?, ?> getCurrentElement() {
return myExtension;
Expand Down Expand Up @@ -2135,11 +2131,11 @@ private void postProcess() {
}
}
}

if (wantedProfileType != null && !wantedProfileType.equals(myInstance.getClass())) {
if (myResourceType == null || myResourceType.isAssignableFrom(wantedProfileType)) {
ourLog.debug("Converting resource of type {} to type defined for profile \"{}\": {}", new Object[] {myInstance.getClass().getName(), usedProfile, wantedProfileType});
ourLog.debug("Converting resource of type {} to type defined for profile \"{}\": {}", new Object[] { myInstance.getClass().getName(), usedProfile, wantedProfileType });

/*
* This isn't the most efficient thing really.. If we want a specific
* type we just re-parse into that type. The problem is that we don't know
Expand All @@ -2162,7 +2158,7 @@ private void postProcess() {
private void stitchBundleCrossReferences() {
final boolean bundle = "Bundle".equals(myContext.getResourceDefinition(myInstance).getName());
if (bundle) {

/*
* Stitch together resource references
*/
Expand Down Expand Up @@ -2200,7 +2196,7 @@ private void stitchBundleCrossReferences() {
}
}
}

}
}

Expand Down Expand Up @@ -2229,11 +2225,11 @@ public PreResourceStateHapi(Object theTarget, IMutator theMutator, Class<? exten
assert theResourceType == null || IResource.class.isAssignableFrom(theResourceType);
}

// @Override
// public void enteringNewElement(String theNamespaceUri, String theLocalPart) throws DataFormatException {
// super.enteringNewElement(theNamespaceUri, theLocalPart);
// populateTarget();
// }
// @Override
// public void enteringNewElement(String theNamespaceUri, String theLocalPart) throws DataFormatException {
// super.enteringNewElement(theNamespaceUri, theLocalPart);
// populateTarget();
// }

@Override
protected void populateTarget() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,21 @@ public void testTransactionCreateWithPutUsingUrl() {
myPatientDao.read(new IdType("Patient/" + methodName), mySrd);
}

@Test
public void testTransactionCreateWithPutUsingAbsoluteUrl() {
String methodName = "testTransactionCreateWithPutUsingAbsoluteUrl";
Bundle request = new Bundle();
request.setType(BundleType.TRANSACTION);

Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.PUT).setUrl("http://localhost/server/base/Patient/" + methodName);

mySystemDao.transaction(mySrd, request);

myPatientDao.read(new IdType("Patient/" + methodName), mySrd);
}

@Test
public void testTransactionCreateWithPutUsingUrl2() throws Exception {
String req = IOUtils.toString(FhirSystemDaoDstu3Test.class.getResourceAsStream("/bundle-dstu3.xml"), StandardCharsets.UTF_8);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public void testContainedResourceInExtensionUndeclared() {
o = (Organization) rr.getResource();
assertEquals("ORG", o.getName());
}

@Test
public void testDuration() {
Encounter enc = new Encounter();
Expand Down Expand Up @@ -236,7 +236,7 @@ public void testEncodeAndParseBundleWithResourceRefs() {
assertEquals("Organization/orgid", pt.getManagingOrganization().getReferenceElement().getValue());
assertSame(org, pt.getManagingOrganization().getResource());
}

@Test
public void testEncodeAndParseCompositeExtension() {
PatientWithCustomCompositeExtension pat = new PatientWithCustomCompositeExtension();
Expand All @@ -253,8 +253,7 @@ public void testEncodeAndParseCompositeExtension() {
assertEquals("ValueA", pat.getFooParentExtension().getChildA().getValue());
assertEquals("ValueB", pat.getFooParentExtension().getChildB().getValue());
}



@Test
public void testEncodeAndParseContained() {
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
Expand Down Expand Up @@ -379,6 +378,7 @@ public void testEncodeAndParseContainedCustomTypes() {
ourCtx = null;
}


@Test
public void testEncodeAndParseContainedNonCustomTypes() {
ourCtx = FhirContext.forDstu3();
Expand Down Expand Up @@ -2742,6 +2742,62 @@ public void testParseContainedBinaryResource() {
assertNotNull(((Reference) actual.getContent().get(0).getP()).getResource());
}

/**
* See #426
*/
@Test
public void testParseExtensionWithIdType() {
//@formatter:off
String input =
"<Patient xmlns=\"http://hl7.org/fhir\">\n" +
" <extension url=\"http://aaa.ch/fhir/Patient#mangedcare\">\n" +
" <extension url=\"http://aaa.ch/fhir/Patient#mangedcare-aaa-id\">\n" +
" <valueId value=\"mc1\"/>\n" +
" </extension>\n" +
" </extension>\n" +
" <identifier>\n" +
" <value value=\"ais111\"/>\n" +
" </identifier>\n" +
"</Patient>";
//@formatter:on
Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, input);

List<Extension> extList = pt.getExtensionsByUrl("http://aaa.ch/fhir/Patient#mangedcare");
extList = extList.get(0).getExtensionsByUrl("http://aaa.ch/fhir/Patient#mangedcare-aaa-id");
Extension ext = extList.get(0);
IdType value = (IdType) ext.getValue();
assertEquals("mc1", value.getValueAsString());
}

/**
* See #426
*
* Value type of FOO isn't a valid datatype
*/
@Test
public void testParseExtensionWithInvalidType() {
//@formatter:off
String input =
"<Patient xmlns=\"http://hl7.org/fhir\">\n" +
" <extension url=\"http://aaa.ch/fhir/Patient#mangedcare\">\n" +
" <extension url=\"http://aaa.ch/fhir/Patient#mangedcare-aaa-id\">\n" +
" <valueFOO value=\"mc1\"/>\n" +
" </extension>\n" +
" </extension>\n" +
" <identifier>\n" +
" <value value=\"ais111\"/>\n" +
" </identifier>\n" +
"</Patient>";
//@formatter:on
Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, input);

List<Extension> extList = pt.getExtensionsByUrl("http://aaa.ch/fhir/Patient#mangedcare");
extList = extList.get(0).getExtensionsByUrl("http://aaa.ch/fhir/Patient#mangedcare-aaa-id");
Extension ext = extList.get(0);
IdType value = (IdType) ext.getValue();
assertEquals(null, value);
}

/**
* See #342
*/
Expand Down
Loading

0 comments on commit a1105fa

Please sign in to comment.