diff --git a/.project b/.project
index 7f72f8d439e..e65da4447c0 100644
--- a/.project
+++ b/.project
@@ -11,8 +11,13 @@
- org.eclipse.m2e.core.maven2Builder
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder.launch
+
diff --git a/hapi-fhir-base/.project b/hapi-fhir-base/.project
index 23adf1aaa35..ea43e2c9d18 100644
--- a/hapi-fhir-base/.project
+++ b/hapi-fhir-base/.project
@@ -16,13 +16,23 @@
- org.eclipse.wst.validation.validationbuilder
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder.launch
+
- org.eclipse.m2e.core.maven2Builder
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (1).launch
+
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IRuntimeDatatypeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IRuntimeDatatypeDefinition.java
index 16226aa1e33..c2a333becf5 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IRuntimeDatatypeDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/IRuntimeDatatypeDefinition.java
@@ -27,7 +27,7 @@ public interface IRuntimeDatatypeDefinition {
boolean isSpecialization();
- public BaseRuntimeElementDefinition> getProfileOf();
+ public Class extends IBaseDatatype> getProfileOf();
boolean isProfileOf(Class extends IBaseDatatype> theType);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java
index 1237879da62..81574a5b1d4 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeChildChoiceDefinition.java
@@ -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> myNameToChildDefinition;
private Map, String> myDatatypeToElementName;
private Map, BaseRuntimeElementDefinition>> myDatatypeToElementDefinition;
+ private String myReferenceSuffix;
public RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List> theChoiceTypes) {
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
@@ -82,9 +85,15 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
myDatatypeToElementName = new HashMap, String>();
myDatatypeToElementDefinition = new HashMap, 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
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeCompositeDatatypeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeCompositeDatatypeDefinition.java
index c7fef549c38..3c2f8351e71 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeCompositeDatatypeDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeCompositeDatatypeDefinition.java
@@ -65,8 +65,8 @@ public class RuntimeCompositeDatatypeDefinition extends BaseRuntimeElementCompos
}
@Override
- public BaseRuntimeElementDefinition> getProfileOf() {
- return myProfileOf;
+ public Class extends IBaseDatatype> getProfileOf() {
+ return myProfileOfType;
}
@Override
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java
index 6288b264d70..619c87a16bb 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimePrimitiveDatatypeDefinition.java
@@ -58,8 +58,8 @@ public class RuntimePrimitiveDatatypeDefinition extends BaseRuntimeElementDefini
}
@Override
- public BaseRuntimeElementDefinition> getProfileOf() {
- return myProfileOf;
+ public Class extends IBaseDatatype> getProfileOf() {
+ return myProfileOfType;
}
@Override
diff --git a/hapi-fhir-jpaserver-base/.project b/hapi-fhir-jpaserver-base/.project
index 68612babd9f..8f94e87b636 100644
--- a/hapi-fhir-jpaserver-base/.project
+++ b/hapi-fhir-jpaserver-base/.project
@@ -17,13 +17,23 @@
- org.eclipse.wst.validation.validationbuilder
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/org.eclipse.wst.validation.validationbuilder (1).launch
+
- org.eclipse.m2e.core.maven2Builder
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder (2).launch
+
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java
index 80e1248c397..6f2f3a83c40 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/subscription/SubscriptionWebsocketHandler.java
@@ -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 paramValues = URLEncodedUtils.parse("http://example.com" + params, Constants.CHARSET_UTF8);
+ String params = theRemaining.substring(theRemaining.indexOf('?')+1);
+ List 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()));
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2Test.java
index 3b5c856aa94..c30151deee2 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2Test.java
@@ -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 {
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java
index fe459441f1b..abc0bb18274 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java
@@ -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()
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SubscriptionsDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SubscriptionsDstu2Test.java
index 3c9baecdcbe..aceac69f4b9 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SubscriptionsDstu2Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SubscriptionsDstu2Test.java
@@ -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);
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 22e1d3cfea5..5945427e7e0 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -95,6 +95,12 @@
JPA server Patient/[id]/$everything operation now supports
_lastUpdated filtering and _sort'ing of results.
+
+ 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!
+