Fix #233 - elementQuantity gets incorrectly encoded as elementDuration
This commit is contained in:
parent
04764ed07e
commit
f9e4a3e1b5
7
.project
7
.project
|
@ -11,8 +11,13 @@
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
<arguments>
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>LaunchConfigHandle</key>
|
||||||
|
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder.launch</value>
|
||||||
|
</dictionary>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
|
|
|
@ -16,13 +16,23 @@
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
<arguments>
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>LaunchConfigHandle</key>
|
||||||
|
<value><project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch</value>
|
||||||
|
</dictionary>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
<arguments>
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>LaunchConfigHandle</key>
|
||||||
|
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (1).launch</value>
|
||||||
|
</dictionary>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
|
|
|
@ -27,7 +27,7 @@ public interface IRuntimeDatatypeDefinition {
|
||||||
|
|
||||||
boolean isSpecialization();
|
boolean isSpecialization();
|
||||||
|
|
||||||
public BaseRuntimeElementDefinition<?> getProfileOf();
|
public Class<? extends IBaseDatatype> getProfileOf();
|
||||||
|
|
||||||
boolean isProfileOf(Class<? extends IBaseDatatype> theType);
|
boolean isProfileOf(Class<? extends IBaseDatatype> theType);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
|
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 ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
|
@ -41,6 +43,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
private Map<String, BaseRuntimeElementDefinition<?>> myNameToChildDefinition;
|
private Map<String, BaseRuntimeElementDefinition<?>> myNameToChildDefinition;
|
||||||
private Map<Class<? extends IBase>, String> myDatatypeToElementName;
|
private Map<Class<? extends IBase>, String> myDatatypeToElementName;
|
||||||
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToElementDefinition;
|
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToElementDefinition;
|
||||||
|
private String myReferenceSuffix;
|
||||||
|
|
||||||
public RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IBase>> theChoiceTypes) {
|
public RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IBase>> theChoiceTypes) {
|
||||||
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
||||||
|
@ -82,9 +85,15 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
myDatatypeToElementName = new HashMap<Class<? extends IBase>, String>();
|
myDatatypeToElementName = new HashMap<Class<? extends IBase>, String>();
|
||||||
myDatatypeToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
myDatatypeToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
||||||
|
|
||||||
|
if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
||||||
|
myReferenceSuffix = "Resource";
|
||||||
|
} else {
|
||||||
|
myReferenceSuffix = "Reference";
|
||||||
|
}
|
||||||
|
|
||||||
for (Class<? extends IBase> next : myChoiceTypes) {
|
for (Class<? extends IBase> next : myChoiceTypes) {
|
||||||
|
|
||||||
String elementName;
|
String elementName = null;
|
||||||
BaseRuntimeElementDefinition<?> nextDef;
|
BaseRuntimeElementDefinition<?> nextDef;
|
||||||
boolean nonPreferred = false;
|
boolean nonPreferred = false;
|
||||||
if (IBaseResource.class.isAssignableFrom(next)) {
|
if (IBaseResource.class.isAssignableFrom(next)) {
|
||||||
|
@ -109,33 +118,44 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
* element fooString when encoded, because markdown is a profile of string. This is according to the
|
* element fooString when encoded, because markdown is a profile of string. This is according to the
|
||||||
* FHIR spec
|
* FHIR spec
|
||||||
*/
|
*/
|
||||||
nextDefForChoice = nextDefDatatype.getProfileOf();
|
nextDefForChoice = null;
|
||||||
nonPreferred = true;
|
nonPreferred = true;
|
||||||
|
Class<? extends IBaseDatatype> profileType = nextDefDatatype.getProfileOf();
|
||||||
|
BaseRuntimeElementDefinition<?> elementDef = theClassToElementDefinitions.get(profileType);
|
||||||
|
elementName = getElementName() + StringUtils.capitalize(elementDef.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (nextDefForChoice != null) {
|
||||||
elementName = getElementName() + StringUtils.capitalize(nextDefForChoice.getName());
|
elementName = getElementName() + StringUtils.capitalize(nextDefForChoice.getName());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// I don't see how elementName could be null here, but eclipse complains..
|
||||||
|
if (elementName != null) {
|
||||||
if (myNameToChildDefinition.containsKey(elementName) == false || !nonPreferred) {
|
if (myNameToChildDefinition.containsKey(elementName) == false || !nonPreferred) {
|
||||||
myNameToChildDefinition.put(elementName, nextDef);
|
myNameToChildDefinition.put(elementName, nextDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IBaseResource.class.isAssignableFrom(next)) {
|
|
||||||
Class<? extends IBase> refType = theContext.getVersion().getResourceReferenceType();
|
|
||||||
myDatatypeToElementDefinition.put(refType, nextDef);
|
|
||||||
|
|
||||||
String alternateElementName;
|
|
||||||
if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
|
||||||
alternateElementName = getElementName() + "Resource";
|
|
||||||
} else {
|
|
||||||
alternateElementName = getElementName() + "Reference";
|
|
||||||
}
|
}
|
||||||
myDatatypeToElementName.put(refType, alternateElementName);
|
|
||||||
|
/*
|
||||||
|
* If this is a resource reference, the element name is "fooNameReference"
|
||||||
|
*/
|
||||||
|
if (IBaseResource.class.isAssignableFrom(next) || IBaseReference.class.isAssignableFrom(next)) {
|
||||||
|
next = theContext.getVersion().getResourceReferenceType();
|
||||||
|
elementName = getElementName() + myReferenceSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
myDatatypeToElementDefinition.put(next, nextDef);
|
myDatatypeToElementDefinition.put(next, nextDef);
|
||||||
|
|
||||||
|
if (myDatatypeToElementName.containsKey(next)) {
|
||||||
|
String existing = myDatatypeToElementName.get(next);
|
||||||
|
if (!existing.equals(elementName)) {
|
||||||
|
throw new ConfigurationException("Already have element name " + existing + " for datatype " + next.getClass().getSimpleName() + " in " + getElementName() + ", cannot add " + elementName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
myDatatypeToElementName.put(next, elementName);
|
myDatatypeToElementName.put(next, elementName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
||||||
myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
|
myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
|
||||||
|
@ -145,7 +165,8 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getChildNameByDatatype(Class<? extends IBase> theDatatype) {
|
public String getChildNameByDatatype(Class<? extends IBase> theDatatype) {
|
||||||
return myDatatypeToElementName.get(theDatatype);
|
String retVal = myDatatypeToElementName.get(theDatatype);
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -65,8 +65,8 @@ public class RuntimeCompositeDatatypeDefinition extends BaseRuntimeElementCompos
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseRuntimeElementDefinition<?> getProfileOf() {
|
public Class<? extends IBaseDatatype> getProfileOf() {
|
||||||
return myProfileOf;
|
return myProfileOfType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -58,8 +58,8 @@ public class RuntimePrimitiveDatatypeDefinition extends BaseRuntimeElementDefini
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseRuntimeElementDefinition<?> getProfileOf() {
|
public Class<? extends IBaseDatatype> getProfileOf() {
|
||||||
return myProfileOf;
|
return myProfileOfType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,13 +17,23 @@
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
<arguments>
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>LaunchConfigHandle</key>
|
||||||
|
<value><project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder (1).launch</value>
|
||||||
|
</dictionary>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||||
|
<triggers>full,incremental,</triggers>
|
||||||
<arguments>
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>LaunchConfigHandle</key>
|
||||||
|
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (2).launch</value>
|
||||||
|
</dictionary>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
|
|
|
@ -119,11 +119,11 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SimpleBoundState implements IState {
|
private class BoundStaticSubscipriptionState implements IState {
|
||||||
|
|
||||||
private WebSocketSession mySession;
|
private WebSocketSession mySession;
|
||||||
|
|
||||||
public SimpleBoundState(WebSocketSession theSession) {
|
public BoundStaticSubscipriptionState(WebSocketSession theSession) {
|
||||||
mySession = theSession;
|
mySession = theSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,12 +157,12 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
||||||
@Autowired
|
@Autowired
|
||||||
private FhirContext myCtx;
|
private FhirContext myCtx;
|
||||||
|
|
||||||
private class ResourceBoundState implements IState {
|
private class BoundDynamicSubscriptionState implements IState {
|
||||||
|
|
||||||
private WebSocketSession mySession;
|
private WebSocketSession mySession;
|
||||||
private EncodingEnum myEncoding;
|
private EncodingEnum myEncoding;
|
||||||
|
|
||||||
public ResourceBoundState(WebSocketSession theSession, EncodingEnum theEncoding) {
|
public BoundDynamicSubscriptionState(WebSocketSession theSession, EncodingEnum theEncoding) {
|
||||||
mySession = theSession;
|
mySession = theSession;
|
||||||
myEncoding = theEncoding;
|
myEncoding = theEncoding;
|
||||||
}
|
}
|
||||||
|
@ -241,12 +241,12 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
||||||
subscription.setCriteria(theRemaining);
|
subscription.setCriteria(theRemaining);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String params = theRemaining.substring(theRemaining.indexOf('?'));
|
String params = theRemaining.substring(theRemaining.indexOf('?')+1);
|
||||||
List<NameValuePair> paramValues = URLEncodedUtils.parse("http://example.com" + params, Constants.CHARSET_UTF8);
|
List<NameValuePair> paramValues = URLEncodedUtils.parse(params, Constants.CHARSET_UTF8, '&');
|
||||||
EncodingEnum encoding = EncodingEnum.JSON;
|
EncodingEnum encoding = EncodingEnum.JSON;
|
||||||
for (NameValuePair nameValuePair : paramValues) {
|
for (NameValuePair nameValuePair : paramValues) {
|
||||||
if (Constants.PARAM_FORMAT.equals(nameValuePair)) {
|
if (Constants.PARAM_FORMAT.equals(nameValuePair.getName())) {
|
||||||
EncodingEnum nextEncoding = EncodingEnum.forContentType(nameValuePair.getValue());
|
EncodingEnum nextEncoding = Constants.FORMAT_VAL_TO_ENCODING.get(nameValuePair.getValue());
|
||||||
if (nextEncoding != null) {
|
if (nextEncoding != null) {
|
||||||
encoding = nextEncoding;
|
encoding = nextEncoding;
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
||||||
|
|
||||||
mySubscriptionPid = mySubscriptionDao.getSubscriptionTablePidForSubscriptionResource(id);
|
mySubscriptionPid = mySubscriptionDao.getSubscriptionTablePidForSubscriptionResource(id);
|
||||||
mySubscriptionId = subscription.getIdElement();
|
mySubscriptionId = subscription.getIdElement();
|
||||||
myState = new ResourceBoundState(theSession, encoding);
|
myState = new BoundDynamicSubscriptionState(theSession, encoding);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
} catch (UnprocessableEntityException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
|
@ -298,7 +298,7 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
||||||
Subscription subscription = mySubscriptionDao.read(id);
|
Subscription subscription = mySubscriptionDao.read(id);
|
||||||
mySubscriptionPid = mySubscriptionDao.getSubscriptionTablePidForSubscriptionResource(id);
|
mySubscriptionPid = mySubscriptionDao.getSubscriptionTablePidForSubscriptionResource(id);
|
||||||
mySubscriptionId = subscription.getIdElement();
|
mySubscriptionId = subscription.getIdElement();
|
||||||
myState = new SimpleBoundState(theSession);
|
myState = new BoundStaticSubscipriptionState(theSession);
|
||||||
} catch (ResourceNotFoundException e) {
|
} catch (ResourceNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
theSession.close(new CloseStatus(CloseStatus.PROTOCOL_ERROR.getCode(), "Invalid bind request - Unknown subscription: " + id.getValue()));
|
theSession.close(new CloseStatus(CloseStatus.PROTOCOL_ERROR.getCode(), "Invalid bind request - Unknown subscription: " + id.getValue()));
|
||||||
|
|
|
@ -1919,6 +1919,10 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
public void testSortByComposite() {
|
public void testSortByComposite() {
|
||||||
|
Observation o = new Observation();
|
||||||
|
o.getCode().setText("testSortByComposite");
|
||||||
|
myObservationDao.create(o);
|
||||||
|
|
||||||
SearchParameterMap pm = new SearchParameterMap();
|
SearchParameterMap pm = new SearchParameterMap();
|
||||||
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_CONCEPT));
|
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_CONCEPT));
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1293,6 +1293,9 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
|
|
||||||
@Test(expected = InvalidRequestException.class)
|
@Test(expected = InvalidRequestException.class)
|
||||||
public void testSearchWithInvalidSort() throws Exception {
|
public void testSearchWithInvalidSort() throws Exception {
|
||||||
|
Observation o = new Observation();
|
||||||
|
o.getCode().setText("testSearchWithInvalidSort");
|
||||||
|
myObservationDao.create(o);
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Bundle found = ourClient
|
Bundle found = ourClient
|
||||||
.search()
|
.search()
|
||||||
|
|
|
@ -176,7 +176,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
WebSocketClient client = new WebSocketClient();
|
WebSocketClient client = new WebSocketClient();
|
||||||
try {
|
try {
|
||||||
client.start();
|
client.start();
|
||||||
URI echoUri = new URI("ws://localhost:" + ourPort + "/baseDstu2/websocket");
|
URI echoUri = new URI("ws://localhost:" + ourPort + "/websocket/dstu2");
|
||||||
client.connect(socket, echoUri, new ClientUpgradeRequest());
|
client.connect(socket, echoUri, new ClientUpgradeRequest());
|
||||||
ourLog.info("Connecting to : {}", echoUri);
|
ourLog.info("Connecting to : {}", echoUri);
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
WebSocketClient client = new WebSocketClient();
|
WebSocketClient client = new WebSocketClient();
|
||||||
try {
|
try {
|
||||||
client.start();
|
client.start();
|
||||||
URI echoUri = new URI("ws://localhost:" + ourPort + "/baseDstu2/websocket");
|
URI echoUri = new URI("ws://localhost:" + ourPort + "/websocket/dstu2");
|
||||||
client.connect(socket, echoUri, new ClientUpgradeRequest());
|
client.connect(socket, echoUri, new ClientUpgradeRequest());
|
||||||
ourLog.info("Connecting to : {}", echoUri);
|
ourLog.info("Connecting to : {}", echoUri);
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,12 @@
|
||||||
JPA server Patient/[id]/$everything operation now supports
|
JPA server Patient/[id]/$everything operation now supports
|
||||||
_lastUpdated filtering and _sort'ing of results.
|
_lastUpdated filtering and _sort'ing of results.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="233">
|
||||||
|
Fix parser issue where profiled choice element datatypes (e.g. value[x] where one allowable
|
||||||
|
type is Duration, which is a profile of Quantity) get incorrectly encoded using the
|
||||||
|
profiled datatype name instead of the base datatype name as required by the FHIR
|
||||||
|
spec. Thanks to Nehashri Puttu Lokesh for reporting!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="1.2" date="2015-09-18">
|
<release version="1.2" date="2015-09-18">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue