Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
a1105fac1e
|
@ -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;
|
||||
|
|
|
@ -10,7 +10,7 @@ package ca.uhn.fhir.parser;
|
|||
* 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,
|
||||
|
@ -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;
|
||||
|
@ -223,7 +224,8 @@ class ParserState<T> {
|
|||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -237,7 +239,8 @@ class ParserState<T> {
|
|||
* @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()) {
|
||||
|
@ -1389,7 +1392,7 @@ class ParserState<T> {
|
|||
@Override
|
||||
public void wereBack() {
|
||||
super.wereBack();
|
||||
|
||||
|
||||
IResource res = (IResource) getCurrentElement();
|
||||
assert res != null;
|
||||
if (res.getId() == null || res.getId().isEmpty()) {
|
||||
|
@ -1582,7 +1585,7 @@ class ParserState<T> {
|
|||
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
|
||||
|
@ -1742,10 +1745,10 @@ class ParserState<T> {
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1773,42 +1776,35 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -2135,11 +2131,11 @@ class ParserState<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -2162,7 +2158,7 @@ class ParserState<T> {
|
|||
private void stitchBundleCrossReferences() {
|
||||
final boolean bundle = "Bundle".equals(myContext.getResourceDefinition(myInstance).getName());
|
||||
if (bundle) {
|
||||
|
||||
|
||||
/*
|
||||
* Stitch together resource references
|
||||
*/
|
||||
|
@ -2200,7 +2196,7 @@ class ParserState<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2229,11 +2225,11 @@ class ParserState<T> {
|
|||
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() {
|
||||
|
|
|
@ -802,6 +802,21 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
|||
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);
|
||||
|
|
|
@ -185,7 +185,7 @@ public class XmlParserDstu3Test {
|
|||
o = (Organization) rr.getResource();
|
||||
assertEquals("ORG", o.getName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDuration() {
|
||||
Encounter enc = new Encounter();
|
||||
|
@ -236,7 +236,7 @@ public class XmlParserDstu3Test {
|
|||
assertEquals("Organization/orgid", pt.getManagingOrganization().getReferenceElement().getValue());
|
||||
assertSame(org, pt.getManagingOrganization().getResource());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeAndParseCompositeExtension() {
|
||||
PatientWithCustomCompositeExtension pat = new PatientWithCustomCompositeExtension();
|
||||
|
@ -253,8 +253,7 @@ public class XmlParserDstu3Test {
|
|||
assertEquals("ValueA", pat.getFooParentExtension().getChildA().getValue());
|
||||
assertEquals("ValueB", pat.getFooParentExtension().getChildB().getValue());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeAndParseContained() {
|
||||
IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
|
||||
|
@ -379,6 +378,7 @@ public class XmlParserDstu3Test {
|
|||
ourCtx = null;
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeAndParseContainedNonCustomTypes() {
|
||||
ourCtx = FhirContext.forDstu3();
|
||||
|
@ -2742,6 +2742,62 @@ public class XmlParserDstu3Test {
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</action>
|
||||
<action type="add">
|
||||
STU3 structure definitions have been updated to the
|
||||
STU3 ballot candidate versions (1.5.0 - SVN 9395)
|
||||
STU3 ballot candidate versions (1.6.0 - SVN 9395)
|
||||
</action>
|
||||
<action type="add">
|
||||
Both client and server now support the new Content Types decided in
|
||||
|
@ -206,6 +206,10 @@
|
|||
Improve performance when parsing resources containing contained resources
|
||||
by eliminating a step where references were woven twice
|
||||
</action>
|
||||
<action type="fix" issue="426">
|
||||
Parser failed to parse resources containing an extension with a value type of
|
||||
"id". Thanks to Raphael Mäder for reporting!
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.6" date="2016-07-07">
|
||||
<action type="fix">
|
||||
|
@ -1457,7 +1461,7 @@
|
|||
search. This is experimental, since it is not a part of the core
|
||||
FHIR specification.
|
||||
</action>
|
||||
<action type="add" fix="250">
|
||||
<action type="add" issue="250">
|
||||
Process "Accept: text/xml" and "Accept: text/json" headers was
|
||||
wanting the equivalent FHIR encoding styles. These are not
|
||||
correct, but the intention is clear so we will honour them
|
||||
|
@ -1468,13 +1472,13 @@
|
|||
codes (specifically, ValueSets which defined concepts containing
|
||||
child concepts did not result in Enum values for the child concepts)
|
||||
</action>
|
||||
<action type="fix" fix="253">
|
||||
<action type="fix" issue="253">
|
||||
In the JPA server, order of transaction processing should be
|
||||
DELETE, POST, PUT, GET, and the order should not matter
|
||||
within entries with the same verb. Thanks to Bill de Beaubien
|
||||
for reporting!
|
||||
</action>
|
||||
<action type="add" fix="254">
|
||||
<action type="add" issue="254">
|
||||
Add the ability to wire JPA conformance providers
|
||||
using Spring (basically, add default constructors
|
||||
and setters to the conformance providers). Thanks
|
||||
|
@ -1571,11 +1575,11 @@
|
|||
<action type="add">
|
||||
JPA server now implements the $validate-code operation
|
||||
</action>
|
||||
<action type="add" fix="125">
|
||||
<action type="add" issue="125">
|
||||
HAPI-FHIR now has support for _summary and _elements parameters, in server, client,
|
||||
and JPA server.
|
||||
</action>
|
||||
<action type="fix" fix="209">
|
||||
<action type="fix" issue="209">
|
||||
_revinclude results from JPA server should have a Bundle.entry.search.mode of
|
||||
"include" and not "match". Thanks to Josh Mandel for reporting!
|
||||
</action>
|
||||
|
@ -1785,7 +1789,7 @@
|
|||
Generic/fluent client and JPA server now both support _lastUpdated search parameter
|
||||
which was added in DSTU2
|
||||
</action>
|
||||
<action name="fix" issue="188">
|
||||
<action type="fix" issue="188">
|
||||
JPA server now supports sorting on reference parameters. Thanks to
|
||||
Vishal Kachroo for reporting that this wasn't working!
|
||||
</action>
|
||||
|
@ -1869,7 +1873,7 @@
|
|||
the new syntax required in DSTU2: [resource name]:[search param NAME]
|
||||
insead of the DSTU1 style [resource name].[search param PATH]
|
||||
</action>
|
||||
<action type="add" fix="124">
|
||||
<action type="add" issue="124">
|
||||
When encoding resources, the parser will now convert any resource
|
||||
references to versionless references automatically (i.e. it will
|
||||
omit the version part automatically if one is present in the reference)
|
||||
|
@ -1878,7 +1882,7 @@
|
|||
reference if the base matches the base for the server giving
|
||||
the response.
|
||||
</action>
|
||||
<action type="fix" fix="130">
|
||||
<action type="fix" issue="130">
|
||||
Narrative generator incorrectly sets the Resource.text.status to 'generated' even if the
|
||||
given resource type does not have a template (and therefore no narrative is actually generated).
|
||||
Thanks to Bill de Beaubien for reporting!
|
||||
|
@ -1886,7 +1890,7 @@
|
|||
<action type="fix">
|
||||
Searching in JPA server with no search parameter returns deleted resources when it should exclude them.
|
||||
</action>
|
||||
<action type="add" fix="135">
|
||||
<action type="add" issue="135">
|
||||
Remove Eclipse and IntelliJ artifacts (.project, *.iml, etc) from version control. Thanks
|
||||
to Doug Martin for the suggestion!
|
||||
</action>
|
||||
|
@ -2075,7 +2079,7 @@
|
|||
the method type was a custom resource definition type (instead of a built-in
|
||||
HAPI type). Thanks to Neal Acharya for the analysis.
|
||||
</action>
|
||||
<action type="add" fix="79">
|
||||
<action type="add" issue="79">
|
||||
JPA server module now supports
|
||||
<![CDATA[<code>_include</code>]]>
|
||||
value of
|
||||
|
|
Loading…
Reference in New Issue