Fix for `userSelected` and `version`. (#5310)
Fix `userSelected` and `version` in tags and security labels to DSTU2 and security labels in JPA storage.
This commit is contained in:
parent
0c42229985
commit
e20382c4c8
|
@ -24,6 +24,7 @@ import ca.uhn.fhir.i18n.Msg;
|
||||||
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
|
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
|
||||||
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
|
import ca.uhn.fhir.model.primitive.BooleanDt;
|
||||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.model.primitive.UriDt;
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
|
@ -58,6 +59,10 @@ public abstract class BaseCodingDt extends BaseIdentifiableElement implements IC
|
||||||
*/
|
*/
|
||||||
public abstract UriDt getSystemElement();
|
public abstract UriDt getSystemElement();
|
||||||
|
|
||||||
|
public abstract StringDt getVersionElement();
|
||||||
|
|
||||||
|
public abstract BooleanDt getUserSelectedElement();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value(s) for <b>display</b> (Representation defined by the system).
|
* Gets the value(s) for <b>display</b> (Representation defined by the system).
|
||||||
* creating it if it does
|
* creating it if it does
|
||||||
|
@ -72,13 +77,6 @@ public abstract class BaseCodingDt extends BaseIdentifiableElement implements IC
|
||||||
|
|
||||||
public abstract BaseCodingDt setDisplay(String theString);
|
public abstract BaseCodingDt setDisplay(String theString);
|
||||||
|
|
||||||
/*
|
|
||||||
todo: handle version
|
|
||||||
public abstract StringDt getVersion();
|
|
||||||
|
|
||||||
public abstract BaseCodingDt setVersion ( String theString);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -181,7 +179,7 @@ public abstract class BaseCodingDt extends BaseIdentifiableElement implements IC
|
||||||
* @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you
|
* @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you
|
||||||
* need this functionality
|
* need this functionality
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated(since = "6.0.0")
|
||||||
@Override
|
@Override
|
||||||
public Boolean getMissing() {
|
public Boolean getMissing() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -193,7 +191,7 @@ public abstract class BaseCodingDt extends BaseIdentifiableElement implements IC
|
||||||
* @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you
|
* @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you
|
||||||
* need this functionality
|
* need this functionality
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated(since = "6.0.0")
|
||||||
@Override
|
@Override
|
||||||
public IQueryParameterType setMissing(Boolean theMissing) {
|
public IQueryParameterType setMissing(Boolean theMissing) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
|
|
|
@ -1033,7 +1033,8 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "system", tag.getScheme());
|
writeOptionalTagWithTextNode(theEventWriter, "system", tag.getScheme());
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "code", tag.getTerm());
|
writeOptionalTagWithTextNode(theEventWriter, "code", tag.getTerm());
|
||||||
writeOptionalTagWithTextNode(theEventWriter, "display", tag.getLabel());
|
writeOptionalTagWithTextNode(theEventWriter, "display", tag.getLabel());
|
||||||
// wipmb should we be writing the new properties here? There must be another path.
|
writeOptionalTagWithTextNode(theEventWriter, "version", tag.getVersion());
|
||||||
|
write(theEventWriter, "userSelected", tag.getUserSelectedBoolean());
|
||||||
theEventWriter.endObject();
|
theEventWriter.endObject();
|
||||||
}
|
}
|
||||||
theEventWriter.endArray();
|
theEventWriter.endArray();
|
||||||
|
|
|
@ -636,7 +636,7 @@ class ParserState<T> {
|
||||||
|
|
||||||
BaseRuntimeElementDefinition<?> target = child.getChildByName(theChildName);
|
BaseRuntimeElementDefinition<?> target = child.getChildByName(theChildName);
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
// This is a bug with the structures and shouldn't happen..
|
// This is a bug with the structures and shouldn't happen.
|
||||||
throw new DataFormatException(
|
throw new DataFormatException(
|
||||||
Msg.code(1809) + "Found unexpected element '" + theChildName + "' in parent element '"
|
Msg.code(1809) + "Found unexpected element '" + theChildName + "' in parent element '"
|
||||||
+ myDefinition.getName() + "'. Valid names are: " + child.getValidChildNames());
|
+ myDefinition.getName() + "'. Valid names are: " + child.getValidChildNames());
|
||||||
|
@ -1584,16 +1584,20 @@ class ParserState<T> {
|
||||||
|
|
||||||
private class TagState extends BaseState {
|
private class TagState extends BaseState {
|
||||||
|
|
||||||
private static final int LABEL = 2;
|
|
||||||
private static final int NONE = 0;
|
private static final int NONE = 0;
|
||||||
|
private static final int TERM = 1;
|
||||||
|
private static final int LABEL = 2;
|
||||||
|
|
||||||
private static final int SCHEME = 3;
|
private static final int SCHEME = 3;
|
||||||
private static final int TERM = 1;
|
private static final int VERSION = 4;
|
||||||
|
private static final int USER_SELECTED = 5;
|
||||||
private String myLabel;
|
private String myLabel;
|
||||||
private String myScheme;
|
private String myScheme;
|
||||||
private int mySubState = 0;
|
private int mySubState = 0;
|
||||||
private TagList myTagList;
|
private TagList myTagList;
|
||||||
private String myTerm;
|
private String myTerm;
|
||||||
|
private String myVersion;
|
||||||
|
private Boolean myUserSelected;
|
||||||
|
|
||||||
public TagState(TagList theTagList) {
|
public TagState(TagList theTagList) {
|
||||||
super(null);
|
super(null);
|
||||||
|
@ -1614,6 +1618,12 @@ class ParserState<T> {
|
||||||
case SCHEME:
|
case SCHEME:
|
||||||
myScheme = (value);
|
myScheme = (value);
|
||||||
break;
|
break;
|
||||||
|
case VERSION:
|
||||||
|
myVersion = (value);
|
||||||
|
break;
|
||||||
|
case USER_SELECTED:
|
||||||
|
myUserSelected = Boolean.valueOf(value);
|
||||||
|
break;
|
||||||
case NONE:
|
case NONE:
|
||||||
// This handles JSON encoding, which is a bit weird
|
// This handles JSON encoding, which is a bit weird
|
||||||
enteringNewElement(null, theName);
|
enteringNewElement(null, theName);
|
||||||
|
@ -1629,7 +1639,9 @@ class ParserState<T> {
|
||||||
mySubState = NONE;
|
mySubState = NONE;
|
||||||
} else {
|
} else {
|
||||||
if (isNotEmpty(myScheme) || isNotBlank(myTerm) || isNotBlank(myLabel)) {
|
if (isNotEmpty(myScheme) || isNotBlank(myTerm) || isNotBlank(myLabel)) {
|
||||||
myTagList.addTag(myScheme, myTerm, myLabel);
|
Tag tag = myTagList.addTag(myScheme, myTerm, myLabel);
|
||||||
|
tag.setUserSelectedBoolean(myUserSelected);
|
||||||
|
tag.setVersion(myVersion);
|
||||||
}
|
}
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
|
@ -1646,6 +1658,10 @@ class ParserState<T> {
|
||||||
mySubState = SCHEME;
|
mySubState = SCHEME;
|
||||||
} else if (Tag.ATTR_LABEL.equals(theLocalPart) || "display".equals(theLocalPart)) {
|
} else if (Tag.ATTR_LABEL.equals(theLocalPart) || "display".equals(theLocalPart)) {
|
||||||
mySubState = LABEL;
|
mySubState = LABEL;
|
||||||
|
} else if ("userSelected".equals(theLocalPart)) {
|
||||||
|
mySubState = USER_SELECTED;
|
||||||
|
} else if ("version".equals(theLocalPart)) {
|
||||||
|
mySubState = VERSION;
|
||||||
} else {
|
} else {
|
||||||
throw new DataFormatException(Msg.code(1818) + "Unexpected element: " + theLocalPart);
|
throw new DataFormatException(Msg.code(1818) + "Unexpected element: " + theLocalPart);
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,8 @@ public class XmlParser extends BaseParser {
|
||||||
|
|
||||||
String namespaceURI = elem.getName().getNamespaceURI();
|
String namespaceURI = elem.getName().getNamespaceURI();
|
||||||
|
|
||||||
if ("extension".equals(elem.getName().getLocalPart())) {
|
String localPart = elem.getName().getLocalPart();
|
||||||
|
if ("extension".equals(localPart)) {
|
||||||
Attribute urlAttr = elem.getAttributeByName(new QName("url"));
|
Attribute urlAttr = elem.getAttributeByName(new QName("url"));
|
||||||
String url;
|
String url;
|
||||||
if (urlAttr == null || isBlank(urlAttr.getValue())) {
|
if (urlAttr == null || isBlank(urlAttr.getValue())) {
|
||||||
|
@ -199,7 +200,7 @@ public class XmlParser extends BaseParser {
|
||||||
url = urlAttr.getValue();
|
url = urlAttr.getValue();
|
||||||
}
|
}
|
||||||
parserState.enteringNewElementExtension(elem, url, false, getServerBaseUrl());
|
parserState.enteringNewElementExtension(elem, url, false, getServerBaseUrl());
|
||||||
} else if ("modifierExtension".equals(elem.getName().getLocalPart())) {
|
} else if ("modifierExtension".equals(localPart)) {
|
||||||
Attribute urlAttr = elem.getAttributeByName(new QName("url"));
|
Attribute urlAttr = elem.getAttributeByName(new QName("url"));
|
||||||
String url;
|
String url;
|
||||||
if (urlAttr == null || isBlank(urlAttr.getValue())) {
|
if (urlAttr == null || isBlank(urlAttr.getValue())) {
|
||||||
|
@ -213,8 +214,7 @@ public class XmlParser extends BaseParser {
|
||||||
}
|
}
|
||||||
parserState.enteringNewElementExtension(elem, url, true, getServerBaseUrl());
|
parserState.enteringNewElementExtension(elem, url, true, getServerBaseUrl());
|
||||||
} else {
|
} else {
|
||||||
String elementName = elem.getName().getLocalPart();
|
parserState.enteringNewElement(namespaceURI, localPart);
|
||||||
parserState.enteringNewElement(namespaceURI, elementName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!heldComments.isEmpty()) {
|
if (!heldComments.isEmpty()) {
|
||||||
|
@ -768,6 +768,11 @@ public class XmlParser extends BaseParser {
|
||||||
writeOptionalTagWithValue(theEventWriter, "system", tag.getScheme());
|
writeOptionalTagWithValue(theEventWriter, "system", tag.getScheme());
|
||||||
writeOptionalTagWithValue(theEventWriter, "code", tag.getTerm());
|
writeOptionalTagWithValue(theEventWriter, "code", tag.getTerm());
|
||||||
writeOptionalTagWithValue(theEventWriter, "display", tag.getLabel());
|
writeOptionalTagWithValue(theEventWriter, "display", tag.getLabel());
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "version", tag.getVersion());
|
||||||
|
Boolean userSelected = tag.getUserSelectedBoolean();
|
||||||
|
if (userSelected != null) {
|
||||||
|
writeOptionalTagWithValue(theEventWriter, "userSelected", userSelected.toString());
|
||||||
|
}
|
||||||
theEventWriter.writeEndElement();
|
theEventWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,13 +151,27 @@ public class InternalCodingDt extends BaseCodingDt implements ICompositeDatatype
|
||||||
* is consistent across versions. However this cannot consistently be assured. and When the meaning is not guaranteed to be consistent, the version SHOULD be exchanged
|
* is consistent across versions. However this cannot consistently be assured. and When the meaning is not guaranteed to be consistent, the version SHOULD be exchanged
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public StringDt getVersion() {
|
@Override
|
||||||
|
public StringDt getVersionElement() {
|
||||||
if (myVersion == null) {
|
if (myVersion == null) {
|
||||||
myVersion = new StringDt();
|
myVersion = new StringDt();
|
||||||
}
|
}
|
||||||
return myVersion;
|
return myVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BooleanDt getUserSelectedElement() {
|
||||||
|
return new BooleanDt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legacy name for {@link #getVersionElement()}
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "7.0.0")
|
||||||
|
public StringDt getVersion() {
|
||||||
|
return getVersionElement();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value(s) for <b>version</b> (Version of the system - if relevant)
|
* Sets the value(s) for <b>version</b> (Version of the system - if relevant)
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 5310
|
||||||
|
title: "Update DSTU2 tags and security labels with support for `userSelected` and `version` elements.
|
||||||
|
Also fix them on security labels in JPA storage."
|
|
@ -32,7 +32,6 @@ import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||||
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
|
||||||
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
|
||||||
import ca.uhn.fhir.jpa.api.dao.IDao;
|
import ca.uhn.fhir.jpa.api.dao.IDao;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IJpaDao;
|
import ca.uhn.fhir.jpa.api.dao.IJpaDao;
|
||||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
|
@ -137,6 +136,7 @@ import org.springframework.transaction.support.TransactionSynchronization;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -227,9 +227,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IInterceptorBroadcaster myInterceptorBroadcaster;
|
protected IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected DaoRegistry myDaoRegistry;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected InMemoryResourceMatcher myInMemoryResourceMatcher;
|
protected InMemoryResourceMatcher myInMemoryResourceMatcher;
|
||||||
|
|
||||||
|
@ -336,8 +333,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
next.getSystemElement().getValue(),
|
next.getSystemElement().getValue(),
|
||||||
next.getCodeElement().getValue(),
|
next.getCodeElement().getValue(),
|
||||||
next.getDisplayElement().getValue(),
|
next.getDisplayElement().getValue(),
|
||||||
null,
|
next.getVersionElement().getValue(),
|
||||||
null);
|
next.getUserSelectedElement().getValue());
|
||||||
if (def != null) {
|
if (def != null) {
|
||||||
ResourceTag tag = theEntity.addTag(def);
|
ResourceTag tag = theEntity.addTag(def);
|
||||||
allDefs.add(tag);
|
allDefs.add(tag);
|
||||||
|
@ -566,11 +563,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
// transaction template can fail if connections to db are exhausted
|
// transaction template can fail if connections to db are exhausted and/or timeout
|
||||||
// and/or timeout
|
ourLog.warn(
|
||||||
ourLog.warn("Transaction failed with: "
|
"Transaction failed with: {}. Transaction will rollback and be reattempted.", ex.getMessage());
|
||||||
+ ex.getMessage() + ". "
|
|
||||||
+ "Transaction will rollback and be reattempted.");
|
|
||||||
retVal = null;
|
retVal = null;
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
|
@ -700,7 +695,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
}
|
}
|
||||||
|
|
||||||
String hashSha256 = hashCode.toString();
|
String hashSha256 = hashCode.toString();
|
||||||
if (hashSha256.equals(theEntity.getHashSha256()) == false) {
|
if (!hashSha256.equals(theEntity.getHashSha256())) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
theEntity.setHashSha256(hashSha256);
|
theEntity.setHashSha256(hashSha256);
|
||||||
|
@ -784,7 +779,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
byte[] resourceBinary;
|
byte[] resourceBinary;
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
case JSON:
|
case JSON:
|
||||||
resourceBinary = encodedResource.getBytes(Charsets.UTF_8);
|
resourceBinary = encodedResource.getBytes(StandardCharsets.UTF_8);
|
||||||
break;
|
break;
|
||||||
case JSONC:
|
case JSONC:
|
||||||
resourceBinary = GZipUtil.compress(encodedResource);
|
resourceBinary = GZipUtil.compress(encodedResource);
|
||||||
|
@ -1592,7 +1587,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
if (!thePerformIndexing
|
if (!thePerformIndexing
|
||||||
&& !savedEntity.isUnchangedInCurrentOperation()
|
&& !savedEntity.isUnchangedInCurrentOperation()
|
||||||
&& !ourDisableIncrementOnUpdateForUnitTest) {
|
&& !ourDisableIncrementOnUpdateForUnitTest) {
|
||||||
if (theResourceId.hasVersionIdPart() == false) {
|
if (!theResourceId.hasVersionIdPart()) {
|
||||||
theResourceId = theResourceId.withVersion(Long.toString(savedEntity.getVersion()));
|
theResourceId = theResourceId.withVersion(Long.toString(savedEntity.getVersion()));
|
||||||
}
|
}
|
||||||
incrementId(theResource, savedEntity, theResourceId);
|
incrementId(theResource, savedEntity, theResourceId);
|
||||||
|
@ -1673,11 +1668,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
||||||
|
|
||||||
protected void addPidToResource(IResourceLookup<JpaPid> theEntity, IBaseResource theResource) {
|
protected void addPidToResource(IResourceLookup<JpaPid> theEntity, IBaseResource theResource) {
|
||||||
if (theResource instanceof IAnyResource) {
|
if (theResource instanceof IAnyResource) {
|
||||||
IDao.RESOURCE_PID.put(
|
IDao.RESOURCE_PID.put(theResource, theEntity.getPersistentId().getId());
|
||||||
(IAnyResource) theResource, theEntity.getPersistentId().getId());
|
|
||||||
} else if (theResource instanceof IResource) {
|
} else if (theResource instanceof IResource) {
|
||||||
IDao.RESOURCE_PID.put(
|
IDao.RESOURCE_PID.put(theResource, theEntity.getPersistentId().getId());
|
||||||
(IResource) theResource, theEntity.getPersistentId().getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -401,11 +401,14 @@ public class JpaStorageResourceParser implements IJpaStorageResourceParser {
|
||||||
secLabel.setSystem(nextTag.getSystem());
|
secLabel.setSystem(nextTag.getSystem());
|
||||||
secLabel.setCode(nextTag.getCode());
|
secLabel.setCode(nextTag.getCode());
|
||||||
secLabel.setDisplay(nextTag.getDisplay());
|
secLabel.setDisplay(nextTag.getDisplay());
|
||||||
// wipmb these technically support userSelected and version
|
secLabel.setVersion(nextTag.getVersion());
|
||||||
|
Boolean userSelected = nextTag.getUserSelected();
|
||||||
|
if (userSelected != null) {
|
||||||
|
secLabel.setUserSelected(userSelected);
|
||||||
|
}
|
||||||
securityLabels.add(secLabel);
|
securityLabels.add(secLabel);
|
||||||
break;
|
break;
|
||||||
case TAG:
|
case TAG:
|
||||||
// wipmb check xml, etc.
|
|
||||||
Tag e = new Tag(nextTag.getSystem(), nextTag.getCode(), nextTag.getDisplay());
|
Tag e = new Tag(nextTag.getSystem(), nextTag.getCode(), nextTag.getDisplay());
|
||||||
e.setVersion(nextTag.getVersion());
|
e.setVersion(nextTag.getVersion());
|
||||||
// careful! These are Boolean, not boolean.
|
// careful! These are Boolean, not boolean.
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.dstu2;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
|
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class FhirResourceDaoDstu2ParseTest extends BaseJpaDstu2Test {
|
||||||
|
@Autowired
|
||||||
|
DaoRegistry myDaoRegistry;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTagRoundTrip() {
|
||||||
|
// given
|
||||||
|
Patient resource = new Patient();
|
||||||
|
IBaseCoding tag = resource.getMeta().addTag();
|
||||||
|
tag.setCode("code");
|
||||||
|
tag.setDisplay("display");
|
||||||
|
tag.setSystem("oid:123");
|
||||||
|
tag.setVersion("v1");
|
||||||
|
tag.setUserSelected(true);
|
||||||
|
|
||||||
|
// when
|
||||||
|
DaoMethodOutcome daoMethodOutcome = myPatientDao.create(resource, mySrd);
|
||||||
|
Patient resourceOut = myPatientDao.read(daoMethodOutcome.getId(), mySrd);
|
||||||
|
|
||||||
|
// then
|
||||||
|
List<? extends IBaseCoding> tags = resourceOut.getMeta().getTag();
|
||||||
|
assertEquals(1, tags.size(), "tag is present");
|
||||||
|
IBaseCoding tagOut = tags.get(0);
|
||||||
|
assertEquals("code", tagOut.getCode());
|
||||||
|
assertEquals("display", tagOut.getDisplay());
|
||||||
|
assertEquals("oid:123", tagOut.getSystem());
|
||||||
|
assertEquals("v1", tagOut.getVersion());
|
||||||
|
assertEquals(true, tagOut.getUserSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSecurityRoundTrip() {
|
||||||
|
// given
|
||||||
|
Patient resource = new Patient();
|
||||||
|
IBaseCoding coding = resource.getMeta().addSecurity();
|
||||||
|
coding.setCode("code");
|
||||||
|
coding.setDisplay("display");
|
||||||
|
coding.setSystem("oid:123");
|
||||||
|
coding.setVersion("v1");
|
||||||
|
coding.setUserSelected(true);
|
||||||
|
|
||||||
|
// when
|
||||||
|
DaoMethodOutcome daoMethodOutcome = myPatientDao.create(resource, mySrd);
|
||||||
|
Patient resourceOut = myPatientDao.read(daoMethodOutcome.getId(), mySrd);
|
||||||
|
|
||||||
|
// then
|
||||||
|
List<? extends IBaseCoding> tags = resourceOut.getMeta().getSecurity();
|
||||||
|
assertEquals(1, tags.size(), "coding is present");
|
||||||
|
IBaseCoding codingOut = tags.get(0);
|
||||||
|
assertEquals("code", codingOut.getCode());
|
||||||
|
assertEquals("display", codingOut.getDisplay());
|
||||||
|
assertEquals("oid:123", codingOut.getSystem());
|
||||||
|
assertEquals("v1", codingOut.getVersion());
|
||||||
|
assertEquals(true, codingOut.getUserSelected());
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.storage.test;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
import ca.uhn.fhir.test.utilities.ITestDataBuilder;
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
|
@ -47,10 +48,10 @@ public class DaoTestDataBuilder implements ITestDataBuilder.WithSupport, ITestDa
|
||||||
|
|
||||||
final FhirContext myFhirCtx;
|
final FhirContext myFhirCtx;
|
||||||
final DaoRegistry myDaoRegistry;
|
final DaoRegistry myDaoRegistry;
|
||||||
SystemRequestDetails mySrd;
|
RequestDetails mySrd;
|
||||||
final SetMultimap<String, IIdType> myIds = HashMultimap.create();
|
final SetMultimap<String, IIdType> myIds = HashMultimap.create();
|
||||||
|
|
||||||
public DaoTestDataBuilder(FhirContext theFhirCtx, DaoRegistry theDaoRegistry, SystemRequestDetails theSrd) {
|
public DaoTestDataBuilder(FhirContext theFhirCtx, DaoRegistry theDaoRegistry, RequestDetails theSrd) {
|
||||||
myFhirCtx = theFhirCtx;
|
myFhirCtx = theFhirCtx;
|
||||||
myDaoRegistry = theDaoRegistry;
|
myDaoRegistry = theDaoRegistry;
|
||||||
mySrd = theSrd;
|
mySrd = theSrd;
|
||||||
|
|
|
@ -134,7 +134,7 @@ public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
public IBaseCoding addSecurity() {
|
public IBaseCoding addSecurity() {
|
||||||
List<BaseCodingDt> tagList = ResourceMetadataKeyEnum.SECURITY_LABELS.get(BaseResource.this);
|
List<BaseCodingDt> tagList = ResourceMetadataKeyEnum.SECURITY_LABELS.get(BaseResource.this);
|
||||||
if (tagList == null) {
|
if (tagList == null) {
|
||||||
tagList = new ArrayList<BaseCodingDt>();
|
tagList = new ArrayList<>();
|
||||||
ResourceMetadataKeyEnum.SECURITY_LABELS.put(BaseResource.this, tagList);
|
ResourceMetadataKeyEnum.SECURITY_LABELS.put(BaseResource.this, tagList);
|
||||||
}
|
}
|
||||||
CodingDt tag = new CodingDt();
|
CodingDt tag = new CodingDt();
|
||||||
|
@ -185,7 +185,7 @@ public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends IPrimitiveType<String>> getProfile() {
|
public List<? extends IPrimitiveType<String>> getProfile() {
|
||||||
ArrayList<IPrimitiveType<String>> retVal = new ArrayList<IPrimitiveType<String>>();
|
ArrayList<IPrimitiveType<String>> retVal = new ArrayList<>();
|
||||||
List<IdDt> profilesList = ResourceMetadataKeyEnum.PROFILES.get(BaseResource.this);
|
List<IdDt> profilesList = ResourceMetadataKeyEnum.PROFILES.get(BaseResource.this);
|
||||||
if (profilesList == null) {
|
if (profilesList == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -198,16 +198,19 @@ public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends IBaseCoding> getSecurity() {
|
public List<? extends IBaseCoding> getSecurity() {
|
||||||
ArrayList<CodingDt> retVal = new ArrayList<CodingDt>();
|
ArrayList<CodingDt> retVal = new ArrayList<>();
|
||||||
List<BaseCodingDt> labelsList = ResourceMetadataKeyEnum.SECURITY_LABELS.get(BaseResource.this);
|
List<BaseCodingDt> labelsList = ResourceMetadataKeyEnum.SECURITY_LABELS.get(BaseResource.this);
|
||||||
if (labelsList == null) {
|
if (labelsList == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
for (BaseCodingDt next : labelsList) {
|
for (BaseCodingDt next : labelsList) {
|
||||||
retVal.add(new CodingDt(
|
CodingDt c = new CodingDt(
|
||||||
next.getSystemElement().getValue(),
|
next.getSystemElement().getValue(),
|
||||||
next.getCodeElement().getValue())
|
next.getCodeElement().getValue());
|
||||||
.setDisplay(next.getDisplayElement().getValue()));
|
c.setDisplay(next.getDisplayElement().getValue());
|
||||||
|
c.setUserSelected(next.getUserSelectedElement());
|
||||||
|
c.setVersion(next.getVersionElement());
|
||||||
|
retVal.add(c);
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +227,7 @@ public abstract class BaseResource extends BaseElement implements IResource {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends IBaseCoding> getTag() {
|
public List<? extends IBaseCoding> getTag() {
|
||||||
ArrayList<IBaseCoding> retVal = new ArrayList<IBaseCoding>();
|
ArrayList<IBaseCoding> retVal = new ArrayList<>();
|
||||||
TagList tagList = ResourceMetadataKeyEnum.TAG_LIST.get(BaseResource.this);
|
TagList tagList = ResourceMetadataKeyEnum.TAG_LIST.get(BaseResource.this);
|
||||||
if (tagList == null) {
|
if (tagList == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
package ca.uhn.fhir.model.dstu2;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
|
import ca.uhn.fhir.parser.IParser;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ModelParseTest {
|
||||||
|
static final Logger ourLog = LoggerFactory.getLogger(ModelParseTest.class);
|
||||||
|
static FhirContext ourFhirContext = FhirContext.forDstu2Cached();
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getParsers")
|
||||||
|
void testTagRoundTrip(IParser theParser) {
|
||||||
|
// given
|
||||||
|
Patient resource = new Patient();
|
||||||
|
IBaseCoding tag = resource.getMeta().addTag();
|
||||||
|
tag.setCode("code");
|
||||||
|
tag.setDisplay("display");
|
||||||
|
tag.setSystem("oid:123");
|
||||||
|
tag.setVersion("v1");
|
||||||
|
tag.setUserSelected(true);
|
||||||
|
|
||||||
|
// when
|
||||||
|
String string = theParser.encodeResourceToString(resource);
|
||||||
|
ourLog.info("encoded: {}", string);
|
||||||
|
Patient bundleOut = theParser.parseResource(Patient.class, string);
|
||||||
|
|
||||||
|
// then
|
||||||
|
List<? extends IBaseCoding> tags = bundleOut.getMeta().getTag();
|
||||||
|
assertEquals(1, tags.size(), "tag is present");
|
||||||
|
IBaseCoding tagOut = tags.get(0);
|
||||||
|
assertEquals("code", tagOut.getCode());
|
||||||
|
assertEquals("display", tagOut.getDisplay());
|
||||||
|
assertEquals("oid:123", tagOut.getSystem());
|
||||||
|
assertEquals("v1", tagOut.getVersion());
|
||||||
|
assertEquals(true, tagOut.getUserSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("getParsers")
|
||||||
|
void testSecurityRoundTrip(IParser theParser) {
|
||||||
|
// given
|
||||||
|
Patient resource = new Patient();
|
||||||
|
IBaseCoding coding = resource.getMeta().addSecurity();
|
||||||
|
coding.setCode("code");
|
||||||
|
coding.setDisplay("display");
|
||||||
|
coding.setSystem("oid:123");
|
||||||
|
coding.setVersion("v1");
|
||||||
|
coding.setUserSelected(true);
|
||||||
|
|
||||||
|
// when
|
||||||
|
String string = theParser.encodeResourceToString(resource);
|
||||||
|
ourLog.info("encoded: {}", string);
|
||||||
|
Patient bundleOut = theParser.parseResource(Patient.class, string);
|
||||||
|
|
||||||
|
// then
|
||||||
|
List<? extends IBaseCoding> labels = bundleOut.getMeta().getSecurity();
|
||||||
|
assertEquals(1, labels.size(), "security is present");
|
||||||
|
IBaseCoding codingOut = labels.get(0);
|
||||||
|
assertEquals("code", codingOut.getCode());
|
||||||
|
assertEquals("display", codingOut.getDisplay());
|
||||||
|
assertEquals("oid:123", codingOut.getSystem());
|
||||||
|
assertEquals("v1", codingOut.getVersion());
|
||||||
|
assertEquals(true, codingOut.getUserSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<IParser> getParsers() {
|
||||||
|
return List.of(
|
||||||
|
ourFhirContext.newJsonParser(),
|
||||||
|
// ourFhirContext.newRDFParser(), dstu2 doesn't support RDF
|
||||||
|
ourFhirContext.newXmlParser()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import ca.uhn.fhir.util.FhirTerser;
|
||||||
import ca.uhn.fhir.util.MetaUtil;
|
import ca.uhn.fhir.util.MetaUtil;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.ICompositeType;
|
import org.hl7.fhir.instance.model.api.ICompositeType;
|
||||||
|
@ -182,8 +183,11 @@ public interface ITestDataBuilder {
|
||||||
return t -> ((IBaseResource)t).setId(theId.toUnqualifiedVersionless());
|
return t -> ((IBaseResource)t).setId(theId.toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
|
|
||||||
default ICreationArgument withTag(String theSystem, String theCode) {
|
default ICreationArgument withTag(String theSystem, String theCode, Consumer<IBaseCoding>... theModifiers) {
|
||||||
return t -> ((IBaseResource)t).getMeta().addTag().setSystem(theSystem).setCode(theCode);
|
return t -> {
|
||||||
|
IBaseCoding coding = ((IBaseResource) t).getMeta().addTag().setSystem(theSystem).setCode(theCode);
|
||||||
|
applyElementModifiers(coding, theModifiers);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
default ICreationArgument withSecurity(String theSystem, String theCode) {
|
default ICreationArgument withSecurity(String theSystem, String theCode) {
|
||||||
|
|
Loading…
Reference in New Issue