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>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
|
|
|
@ -16,13 +16,23 @@
|
|||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (1).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
|
|
|
@ -27,7 +27,7 @@ public interface IRuntimeDatatypeDefinition {
|
|||
|
||||
boolean isSpecialization();
|
||||
|
||||
public BaseRuntimeElementDefinition<?> getProfileOf();
|
||||
public Class<? extends IBaseDatatype> getProfileOf();
|
||||
|
||||
boolean isProfileOf(Class<? extends IBaseDatatype> theType);
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ import java.util.Set;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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 ca.uhn.fhir.model.api.annotation.Child;
|
||||
|
@ -41,6 +43,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
private Map<String, BaseRuntimeElementDefinition<?>> myNameToChildDefinition;
|
||||
private Map<Class<? extends IBase>, String> myDatatypeToElementName;
|
||||
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) {
|
||||
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
||||
|
@ -82,9 +85,15 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
myDatatypeToElementName = new HashMap<Class<? extends IBase>, String>();
|
||||
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) {
|
||||
|
||||
String elementName;
|
||||
String elementName = null;
|
||||
BaseRuntimeElementDefinition<?> nextDef;
|
||||
boolean nonPreferred = false;
|
||||
if (IBaseResource.class.isAssignableFrom(next)) {
|
||||
|
@ -109,32 +118,43 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
* element fooString when encoded, because markdown is a profile of string. This is according to the
|
||||
* FHIR spec
|
||||
*/
|
||||
nextDefForChoice = nextDefDatatype.getProfileOf();
|
||||
nextDefForChoice = null;
|
||||
nonPreferred = true;
|
||||
Class<? extends IBaseDatatype> profileType = nextDefDatatype.getProfileOf();
|
||||
BaseRuntimeElementDefinition<?> elementDef = theClassToElementDefinitions.get(profileType);
|
||||
elementName = getElementName() + StringUtils.capitalize(elementDef.getName());
|
||||
}
|
||||
}
|
||||
elementName = getElementName() + StringUtils.capitalize(nextDefForChoice.getName());
|
||||
}
|
||||
|
||||
if (myNameToChildDefinition.containsKey(elementName) == false || !nonPreferred) {
|
||||
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";
|
||||
if (nextDefForChoice != null) {
|
||||
elementName = getElementName() + StringUtils.capitalize(nextDefForChoice.getName());
|
||||
}
|
||||
myDatatypeToElementName.put(refType, alternateElementName);
|
||||
}
|
||||
|
||||
// I don't see how elementName could be null here, but eclipse complains..
|
||||
if (elementName != null) {
|
||||
if (myNameToChildDefinition.containsKey(elementName) == false || !nonPreferred) {
|
||||
myNameToChildDefinition.put(elementName, nextDef);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
myDatatypeToElementName.put(next, elementName);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
||||
|
@ -145,7 +165,8 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
|
||||
@Override
|
||||
public String getChildNameByDatatype(Class<? extends IBase> theDatatype) {
|
||||
return myDatatypeToElementName.get(theDatatype);
|
||||
String retVal = myDatatypeToElementName.get(theDatatype);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -65,8 +65,8 @@ public class RuntimeCompositeDatatypeDefinition extends BaseRuntimeElementCompos
|
|||
}
|
||||
|
||||
@Override
|
||||
public BaseRuntimeElementDefinition<?> getProfileOf() {
|
||||
return myProfileOf;
|
||||
public Class<? extends IBaseDatatype> getProfileOf() {
|
||||
return myProfileOfType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -58,8 +58,8 @@ public class RuntimePrimitiveDatatypeDefinition extends BaseRuntimeElementDefini
|
|||
}
|
||||
|
||||
@Override
|
||||
public BaseRuntimeElementDefinition<?> getProfileOf() {
|
||||
return myProfileOf;
|
||||
public Class<? extends IBaseDatatype> getProfileOf() {
|
||||
return myProfileOfType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,13 +17,23 @@
|
|||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder (1).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (2).launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
|
|
|
@ -119,11 +119,11 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
|||
}
|
||||
}
|
||||
|
||||
private class SimpleBoundState implements IState {
|
||||
private class BoundStaticSubscipriptionState implements IState {
|
||||
|
||||
private WebSocketSession mySession;
|
||||
|
||||
public SimpleBoundState(WebSocketSession theSession) {
|
||||
public BoundStaticSubscipriptionState(WebSocketSession theSession) {
|
||||
mySession = theSession;
|
||||
}
|
||||
|
||||
|
@ -157,12 +157,12 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
|||
@Autowired
|
||||
private FhirContext myCtx;
|
||||
|
||||
private class ResourceBoundState implements IState {
|
||||
private class BoundDynamicSubscriptionState implements IState {
|
||||
|
||||
private WebSocketSession mySession;
|
||||
private EncodingEnum myEncoding;
|
||||
|
||||
public ResourceBoundState(WebSocketSession theSession, EncodingEnum theEncoding) {
|
||||
public BoundDynamicSubscriptionState(WebSocketSession theSession, EncodingEnum theEncoding) {
|
||||
mySession = theSession;
|
||||
myEncoding = theEncoding;
|
||||
}
|
||||
|
@ -241,12 +241,12 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
|||
subscription.setCriteria(theRemaining);
|
||||
|
||||
try {
|
||||
String params = theRemaining.substring(theRemaining.indexOf('?'));
|
||||
List<NameValuePair> paramValues = URLEncodedUtils.parse("http://example.com" + params, Constants.CHARSET_UTF8);
|
||||
String params = theRemaining.substring(theRemaining.indexOf('?')+1);
|
||||
List<NameValuePair> paramValues = URLEncodedUtils.parse(params, Constants.CHARSET_UTF8, '&');
|
||||
EncodingEnum encoding = EncodingEnum.JSON;
|
||||
for (NameValuePair nameValuePair : paramValues) {
|
||||
if (Constants.PARAM_FORMAT.equals(nameValuePair)) {
|
||||
EncodingEnum nextEncoding = EncodingEnum.forContentType(nameValuePair.getValue());
|
||||
if (Constants.PARAM_FORMAT.equals(nameValuePair.getName())) {
|
||||
EncodingEnum nextEncoding = Constants.FORMAT_VAL_TO_ENCODING.get(nameValuePair.getValue());
|
||||
if (nextEncoding != null) {
|
||||
encoding = nextEncoding;
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
|||
|
||||
mySubscriptionPid = mySubscriptionDao.getSubscriptionTablePidForSubscriptionResource(id);
|
||||
mySubscriptionId = subscription.getIdElement();
|
||||
myState = new ResourceBoundState(theSession, encoding);
|
||||
myState = new BoundDynamicSubscriptionState(theSession, encoding);
|
||||
|
||||
return id;
|
||||
} catch (UnprocessableEntityException e) {
|
||||
|
@ -298,7 +298,7 @@ public class SubscriptionWebsocketHandler extends TextWebSocketHandler implement
|
|||
Subscription subscription = mySubscriptionDao.read(id);
|
||||
mySubscriptionPid = mySubscriptionDao.getSubscriptionTablePidForSubscriptionResource(id);
|
||||
mySubscriptionId = subscription.getIdElement();
|
||||
myState = new SimpleBoundState(theSession);
|
||||
myState = new BoundStaticSubscipriptionState(theSession);
|
||||
} catch (ResourceNotFoundException e) {
|
||||
try {
|
||||
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()
|
||||
public void testSortByComposite() {
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("testSortByComposite");
|
||||
myObservationDao.create(o);
|
||||
|
||||
SearchParameterMap pm = new SearchParameterMap();
|
||||
pm.setSort(new SortSpec(Observation.SP_CODE_VALUE_CONCEPT));
|
||||
try {
|
||||
|
|
|
@ -1293,6 +1293,9 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
@Test(expected = InvalidRequestException.class)
|
||||
public void testSearchWithInvalidSort() throws Exception {
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("testSearchWithInvalidSort");
|
||||
myObservationDao.create(o);
|
||||
//@formatter:off
|
||||
Bundle found = ourClient
|
||||
.search()
|
||||
|
|
|
@ -176,7 +176,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
WebSocketClient client = new WebSocketClient();
|
||||
try {
|
||||
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());
|
||||
ourLog.info("Connecting to : {}", echoUri);
|
||||
|
||||
|
@ -241,7 +241,7 @@ public class SubscriptionsDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
WebSocketClient client = new WebSocketClient();
|
||||
try {
|
||||
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());
|
||||
ourLog.info("Connecting to : {}", echoUri);
|
||||
|
||||
|
|
|
@ -95,6 +95,12 @@
|
|||
JPA server Patient/[id]/$everything operation now supports
|
||||
_lastUpdated filtering and _sort'ing of results.
|
||||
</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 version="1.2" date="2015-09-18">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue