diff --git a/example-projects/hapi-fhir-jpaserver-cds-example/pom.xml b/example-projects/hapi-fhir-jpaserver-cds-example/pom.xml
index 4d600fe1ba8..ff31307337e 100644
--- a/example-projects/hapi-fhir-jpaserver-cds-example/pom.xml
+++ b/example-projects/hapi-fhir-jpaserver-cds-example/pom.xml
@@ -224,13 +224,17 @@
-
+
+
- org.apache.maven.plugins
- maven-compiler-plugin
+ org.owasp
+ dependency-check-maven
- 1.7
- 1.7
+ 99
+ false
diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml
index a947d8fecef..f9559a6362a 100644
--- a/hapi-fhir-base/pom.xml
+++ b/hapi-fhir-base/pom.xml
@@ -10,7 +10,7 @@
hapi-fhir-base
- jar
+ bundle
http://jamesagnew.github.io/hapi-fhir/
@@ -150,6 +150,21 @@
-->
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+
+ ca.uhn.fhir.rest.api.server;resolution:=optional,
+ ca.uhn.fhir.model.api;resolution:=optional,
+ *
+
+
+
+
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/StopWatch.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/StopWatch.java
index 63c9fe115a2..9ad4acc1908 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/StopWatch.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/StopWatch.java
@@ -20,9 +20,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* Licensed under the Apache License, Version 2.0 (the "License");
* 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
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml
index f9abc66d9be..00d03f7a02b 100644
--- a/hapi-fhir-client/pom.xml
+++ b/hapi-fhir-client/pom.xml
@@ -9,7 +9,7 @@
hapi-fhir-client
- jar
+ bundle
HAPI FHIR - Client Framework
@@ -69,6 +69,18 @@
@{argLine} -Dfile.encoding=UTF-8 -Xmx712m
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml
index d57d06bca18..465c0dc121f 100644
--- a/hapi-fhir-converter/pom.xml
+++ b/hapi-fhir-converter/pom.xml
@@ -10,7 +10,7 @@
hapi-fhir-converter
- jar
+ bundle
@@ -134,5 +134,21 @@
false
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.fhir.rest.server*;resolution:=optional,
+ javax.servlet.http;resolution:=optional,
+ *
+
+
+
+
+
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
index 9f6491c6b86..b804e2fa6cb 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
@@ -60,6 +60,9 @@ public class DaoConfig {
* update setter javadoc if default changes
*/
private boolean myAllowExternalReferences = false;
+ /**
+ * update setter javadoc if default changes
+ */
private boolean myAllowContainsSearches = true;
/**
@@ -137,6 +140,7 @@ public class DaoConfig {
myTreatReferencesAsLogical.add(theTreatReferencesAsLogical);
}
+
/**
* Specifies the highest number that a client is permitted to use in a
* Cache-Control: nostore, max-results=NNN
@@ -376,9 +380,9 @@ public class DaoConfig {
* of higher importance than raw write performance
*
*
- * Note that this setting also has an impact on sorting (i.e. using the
- * _sort
parameter on searches): If the server is configured
- * to not index missing field.
+ * Note that this setting also has an impact on sorting (i.e. using the
+ * _sort
parameter on searches): If the server is configured
+ * to not index missing field.
*
*/
public void setIndexMissingFields(IndexEnabledEnum theIndexMissingFields) {
@@ -650,6 +654,26 @@ public class DaoConfig {
return this;
}
+ /**
+ * If enabled, the server will support the use of :contains searches,
+ * which are helpful but can have adverse effects on performance.
+ *
+ * Default is true
+ */
+ public boolean isAllowContainsSearches() {
+ return myAllowContainsSearches;
+ }
+
+ /**
+ * If enabled, the server will support the use of :contains searches,
+ * which are helpful but can have adverse effects on performance.
+ *
+ * Default is true
+ */
+ public void setAllowContainsSearches(boolean theAllowContainsSearches) {
+ this.myAllowContainsSearches = theAllowContainsSearches;
+ }
+
/**
* If set to true
(default is false
) the server will allow
* resources to have references to external servers. For example if this server is
@@ -1099,16 +1123,6 @@ public class DaoConfig {
}
- public boolean allowContainsSearches() {
-
- return myAllowContainsSearches;
- }
-
- public void setAllowContainsSearches(boolean myAllowContainsSearches) {
-
- this.myAllowContainsSearches = myAllowContainsSearches;
- }
-
public enum IndexEnabledEnum {
ENABLED,
DISABLED
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchBuilder.java
index b9a5dfa18cb..f78f8617f90 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchBuilder.java
@@ -20,29 +20,32 @@ package ca.uhn.fhir.jpa.dao;
* #L%
*/
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.model.api.Include;
+import ca.uhn.fhir.rest.param.DateRangeParam;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+
+import javax.persistence.EntityManager;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
-import javax.persistence.EntityManager;
-
-import org.hl7.fhir.instance.model.api.IBaseResource;
-
-import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.fhir.model.api.Include;
-import ca.uhn.fhir.rest.param.DateRangeParam;
-
public interface ISearchBuilder {
Iterator createQuery(SearchParameterMap theParams, String theSearchUuid);
- void setType(Class extends IBaseResource> theResourceType, String theResourceName);
-
void loadResourcesByPid(Collection theIncludePids, List theResourceListToPopulate, Set theRevIncludedPids, boolean theForHistoryOperation, EntityManager theEntityManager,
- FhirContext theContext, IDao theDao);
+ FhirContext theContext, IDao theDao);
Set loadReverseIncludes(IDao theCallingDao, FhirContext theContext, EntityManager theEntityManager, Collection theMatches, Set theRevIncludes, boolean theReverseMode,
- DateRangeParam theLastUpdated);
+ DateRangeParam theLastUpdated);
+
+ /**
+ * How many results may be fetched at once
+ */
+ void setFetchSize(int theFetchSize);
+
+ void setType(Class extends IBaseResource> theResourceType, String theResourceName);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
index 293514954fa..2469110cda2 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
@@ -28,8 +28,6 @@ import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.jpa.util.BaseIterator;
-import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
-import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
@@ -45,7 +43,9 @@ import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
+import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.UrlUtil;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
@@ -59,6 +59,9 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.tuple.Pair;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
+import org.hibernate.engine.spi.EntityKey;
+import org.hibernate.engine.spi.PersistenceContext;
+import org.hibernate.internal.SessionImpl;
import org.hibernate.query.Query;
import org.hl7.fhir.dstu3.model.BaseResource;
import org.hl7.fhir.instance.model.api.IAnyResource;
@@ -104,6 +107,7 @@ public class SearchBuilder implements ISearchBuilder {
private ISearchParamRegistry mySearchParamRegistry;
private String mySearchUuid;
private IHapiTerminologySvc myTerminologySvc;
+ private int myFetchSize;
/**
* Constructor
@@ -1091,10 +1095,10 @@ public class SearchBuilder implements ISearchBuilder {
} else if (theParameter instanceof StringParam) {
StringParam id = (StringParam) theParameter;
rawSearchTerm = id.getValue();
- if ((id.isContains()) &&
- (!myCallingDao.getConfig().allowContainsSearches()))
- {
- throw new MethodNotAllowedException(":contains modifier is disabled on this server");
+ if (id.isContains()) {
+ if (!myCallingDao.getConfig().isAllowContainsSearches()) {
+ throw new MethodNotAllowedException(":contains modifier is disabled on this server");
+ }
}
} else if (theParameter instanceof IPrimitiveDatatype>) {
IPrimitiveDatatype> id = (IPrimitiveDatatype>) theParameter;
@@ -1109,18 +1113,11 @@ public class SearchBuilder implements ISearchBuilder {
}
String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
- if (myCallingDao.getConfig().allowContainsSearches()) {
- if (theParameter instanceof StringParam) {
- if (((StringParam) theParameter).isContains()) {
- likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
- } else {
- likeExpression = createLeftMatchLikeExpression(likeExpression);
- }
- } else {
- likeExpression = createLeftMatchLikeExpression(likeExpression);
- }
- }
- else {
+ if (theParameter instanceof StringParam &&
+ ((StringParam) theParameter).isContains() &&
+ myCallingDao.getConfig().isAllowContainsSearches()) {
+ likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
+ } else {
likeExpression = createLeftMatchLikeExpression(likeExpression);
}
@@ -1933,6 +1930,11 @@ public class SearchBuilder implements ISearchBuilder {
}
}
+ @Override
+ public void setFetchSize(int theFetchSize) {
+ myFetchSize = theFetchSize;
+ }
+
@Override
public void setType(Class extends IBaseResource> theResourceType, String theResourceName) {
myResourceType = theResourceType;
@@ -2020,14 +2022,14 @@ public class SearchBuilder implements ISearchBuilder {
return lastUpdatedPredicates;
}
- private static String createLeftMatchLikeExpression(String likeExpression) {
- return likeExpression.replace("%", "[%]") + "%";
- }
-
private static String createLeftAndRightMatchLikeExpression(String likeExpression) {
return "%" + likeExpression.replace("%", "[%]") + "%";
}
+ private static String createLeftMatchLikeExpression(String likeExpression) {
+ return likeExpression.replace("%", "[%]") + "%";
+ }
+
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From, ? extends ResourceLink> theFrom,
String theResourceType) {
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(theResourceType);
@@ -2188,6 +2190,7 @@ public class SearchBuilder implements ISearchBuilder {
final TypedQuery query = createQuery(mySort, maximumResults);
Query hibernateQuery = (Query) query;
+ hibernateQuery.setFetchSize(myFetchSize);
ScrollableResults scroll = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
myResultsIterator = new ScrollableResultsIterator(scroll);
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java
index 8ffef936f9f..c7a959763e6 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/SearchCoordinatorSvcImpl.java
@@ -206,6 +206,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
Class extends IBaseResource> resourceTypeClass = myContext.getResourceDefinition(theResourceType).getImplementingClass();
final ISearchBuilder sb = theCallingDao.newSearchBuilder();
sb.setType(resourceTypeClass, theResourceType);
+ sb.setFetchSize(mySyncSize);
final Integer loadSynchronousUpTo;
if (theCacheControlDirective != null && theCacheControlDirective.isNoStore()) {
@@ -233,7 +234,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
public SimpleBundleProvider doInTransaction(TransactionStatus theStatus) {
// Load the results synchronously
- final List pids = new ArrayList();
+ final List pids = new ArrayList<>();
Iterator resultIter = sb.createQuery(theParams, searchUuid);
while (resultIter.hasNext()) {
@@ -458,8 +459,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private final SearchParameterMap myParams;
private final String myResourceType;
private final Search mySearch;
- private final ArrayList mySyncedPids = new ArrayList();
- private final ArrayList myUnsyncedPids = new ArrayList();
+ private final ArrayList mySyncedPids = new ArrayList<>();
+ private final ArrayList myUnsyncedPids = new ArrayList<>();
private boolean myAbortRequested;
private int myCountSaved = 0;
private String mySearchUuid;
@@ -503,7 +504,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
* It is called automatically by the thread pool.
*/
@Override
- public Void call() throws Exception {
+ public Void call() {
StopWatch sw = new StopWatch();
try {
@@ -631,10 +632,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
boolean keepWaiting;
do {
synchronized (mySyncedPids) {
- keepWaiting = false;
- if (mySyncedPids.size() < theToIndex && mySearch.getStatus() == SearchStatusEnum.LOADING) {
- keepWaiting = true;
- }
+ keepWaiting = mySyncedPids.size() < theToIndex && mySearch.getStatus() == SearchStatusEnum.LOADING;
}
if (keepWaiting) {
ourLog.info("Waiting, as we only have {} results", mySyncedPids.size());
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java
index 05185a32150..514a71d2b5a 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java
@@ -11,6 +11,7 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -54,6 +55,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
public void afterResetSearchSize() {
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
+ myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
}
@Before
@@ -1404,43 +1406,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
}
}
- /**
- * See #819
- */
- @Test
- public void testSearchTokenWithNotModifier() {
- String male, female;
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("001");
- patient.addName().setFamily("Tester").addGiven("Joe");
- patient.setGender(AdministrativeGender.MALE);
- male = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
- }
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("002");
- patient.addName().setFamily("Tester").addGiven("Jane");
- patient.setGender(AdministrativeGender.FEMALE);
- female = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
- }
-
- List patients;
- SearchParameterMap params;
-
- params = new SearchParameterMap();
- params.add(Patient.SP_GENDER, new TokenParam(null, "male"));
- params.setLoadSynchronous(true);
- patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
- assertThat(patients, contains(male));
-
- params = new SearchParameterMap();
- params.add(Patient.SP_GENDER, new TokenParam(null, "male").setModifier(TokenParamModifier.NOT));
- params.setLoadSynchronous(true);
- patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
- assertThat(patients, contains(female));
- }
-
@Test
public void testSearchNumberParam() {
ImmunizationRecommendation e1 = new ImmunizationRecommendation();
@@ -2122,6 +2087,43 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
}
}
+ /**
+ * See #819
+ */
+ @Test
+ public void testSearchTokenWithNotModifier() {
+ String male, female;
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("001");
+ patient.addName().setFamily("Tester").addGiven("Joe");
+ patient.setGender(AdministrativeGender.MALE);
+ male = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
+ }
+ {
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("urn:system").setValue("002");
+ patient.addName().setFamily("Tester").addGiven("Jane");
+ patient.setGender(AdministrativeGender.FEMALE);
+ female = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
+ }
+
+ List patients;
+ SearchParameterMap params;
+
+ params = new SearchParameterMap();
+ params.add(Patient.SP_GENDER, new TokenParam(null, "male"));
+ params.setLoadSynchronous(true);
+ patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
+ assertThat(patients, contains(male));
+
+ params = new SearchParameterMap();
+ params.add(Patient.SP_GENDER, new TokenParam(null, "male").setModifier(TokenParamModifier.NOT));
+ params.setLoadSynchronous(true);
+ patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
+ assertThat(patients, contains(female));
+ }
+
@Test
public void testSearchTokenWrongParam() {
Patient p1 = new Patient();
@@ -2257,6 +2259,67 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
}
+ @Test
+ public void testSearchWithContains() {
+
+ Patient pt1 = new Patient();
+ pt1.addName().setFamily("ABCDEFGHIJK");
+ String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
+
+ Patient pt2 = new Patient();
+ pt2.addName().setFamily("FGHIJK");
+ String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue();
+
+ Patient pt3 = new Patient();
+ pt3.addName().setFamily("ZZZZZ");
+ myPatientDao.create(pt3).getId().toUnqualifiedVersionless().getValue();
+
+
+ List ids;
+ SearchParameterMap map;
+ IBundleProvider results;
+
+ // Contains = true
+ map = new SearchParameterMap();
+ map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(true));
+ map.setLoadSynchronous(true);
+ results = myPatientDao.search(map);
+ ids = toUnqualifiedVersionlessIdValues(results);
+ assertThat(ids, containsInAnyOrder(pt1id, pt2id));
+
+ // Contains = false
+ map = new SearchParameterMap();
+ map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(false));
+ map.setLoadSynchronous(true);
+ results = myPatientDao.search(map);
+ ids = toUnqualifiedVersionlessIdValues(results);
+ assertThat(ids, containsInAnyOrder(pt2id));
+
+ // No contains
+ map = new SearchParameterMap();
+ map.add(Patient.SP_NAME, new StringParam("FGHIJK"));
+ map.setLoadSynchronous(true);
+ results = myPatientDao.search(map);
+ ids = toUnqualifiedVersionlessIdValues(results);
+ assertThat(ids, containsInAnyOrder(pt2id));
+ }
+
+ @Test
+ public void testSearchWithContainsDisabled() {
+ myDaoConfig.setAllowContainsSearches(false);
+
+ SearchParameterMap map = new SearchParameterMap();
+ map.setLoadSynchronous(true);
+ map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(true));
+
+ try {
+ myPatientDao.search(map);
+ fail();
+ } catch (MethodNotAllowedException e) {
+ assertEquals(":contains modifier is disabled on this server", e.getMessage());
+ }
+ }
+
@Test
public void testSearchWithDate() {
IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu2Config.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu2Config.java
index 0ba5259d270..d84ad94ec41 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu2Config.java
+++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu2Config.java
@@ -68,6 +68,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseDstu2");
retVal.setCountSearchResultsUpTo(TestR4Config.COUNT_SEARCH_RESULTS_UP_TO);
retVal.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);
+ retVal.setFetchSizeDefaultMaximum(10000);
return retVal;
}
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu3Config.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu3Config.java
index 845433ba7bd..7c3f868a25b 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu3Config.java
+++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestDstu3Config.java
@@ -57,6 +57,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseDstu3");
retVal.setCountSearchResultsUpTo(TestR4Config.COUNT_SEARCH_RESULTS_UP_TO);
retVal.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);
+ retVal.setFetchSizeDefaultMaximum(10000);
return retVal;
}
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java
index 6a96849ea0a..1953d6d945f 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java
+++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java
@@ -58,6 +58,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
retVal.getTreatBaseUrlsAsLocal().add("https://fhirtest.uhn.ca/baseR4");
retVal.setIndexMissingFields(DaoConfig.IndexEnabledEnum.ENABLED);
retVal.setCountSearchResultsUpTo(TestR4Config.COUNT_SEARCH_RESULTS_UP_TO);
+ retVal.setFetchSizeDefaultMaximum(10000);
return retVal;
}
diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml
index c6448786624..edbd2da2f22 100644
--- a/hapi-fhir-structures-dstu2.1/pom.xml
+++ b/hapi-fhir-structures-dstu2.1/pom.xml
@@ -10,7 +10,7 @@
hapi-fhir-structures-dstu2.1
- jar
+ bundle
HAPI FHIR Structures - DSTU2.1 (2016May)
@@ -273,6 +273,22 @@
true
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+ javax.servlet*;resolution:=optional,
+ *
+
+
+
+
diff --git a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java
index ebbfbc2a0dd..fa98150221c 100644
--- a/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java
+++ b/hapi-fhir-structures-dstu2.1/src/main/java/org/hl7/fhir/dstu2016may/hapi/validation/DefaultProfileValidationSupport.java
@@ -2,6 +2,7 @@ package org.hl7.fhir.dstu2016may.hapi.validation;
import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.Charsets;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu2016may.model.*;
import org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent;
@@ -68,8 +69,8 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
Map codeSystems = myCodeSystems;
Map valueSets = myValueSets;
if (codeSystems == null) {
- codeSystems = new HashMap();
- valueSets = new HashMap();
+ codeSystems = new HashMap<>();
+ valueSets = new HashMap<>();
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/model/valueset/valuesets.xml");
loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu2016may/model/valueset/v2-tables.xml");
@@ -155,27 +156,33 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
private void loadCodeSystems(FhirContext theContext, Map theCodeSystems, Map theValueSets, String theClasspath) {
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
- InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
- if (valuesetText != null) {
- InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
+ InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
+ InputStreamReader reader = null;
+ if (inputStream != null) {
+ try {
+ reader = new InputStreamReader(inputStream, Charsets.UTF_8);
- Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
- for (BundleEntryComponent next : bundle.getEntry()) {
- if (next.getResource() instanceof CodeSystem) {
- CodeSystem nextValueSet = (CodeSystem) next.getResource();
- nextValueSet.getText().setDivAsString("");
- String system = nextValueSet.getUrl();
- if (isNotBlank(system)) {
- theCodeSystems.put(system, nextValueSet);
- }
- } else if (next.getResource() instanceof ValueSet) {
- ValueSet nextValueSet = (ValueSet) next.getResource();
- nextValueSet.getText().setDivAsString("");
- String system = nextValueSet.getUrl();
- if (isNotBlank(system)) {
- theValueSets.put(system, nextValueSet);
+ Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
+ for (BundleEntryComponent next : bundle.getEntry()) {
+ if (next.getResource() instanceof CodeSystem) {
+ CodeSystem nextValueSet = (CodeSystem) next.getResource();
+ nextValueSet.getText().setDivAsString("");
+ String system = nextValueSet.getUrl();
+ if (isNotBlank(system)) {
+ theCodeSystems.put(system, nextValueSet);
+ }
+ } else if (next.getResource() instanceof ValueSet) {
+ ValueSet nextValueSet = (ValueSet) next.getResource();
+ nextValueSet.getText().setDivAsString("");
+ String system = nextValueSet.getUrl();
+ if (isNotBlank(system)) {
+ theValueSets.put(system, nextValueSet);
+ }
}
}
+ } finally {
+ IOUtils.closeQuietly(reader);
+ IOUtils.closeQuietly(inputStream);
}
} else {
ourLog.warn("Unable to load resource: {}", theClasspath);
diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml
index 2a0c42c68c9..67b81dd56b7 100644
--- a/hapi-fhir-structures-dstu2/pom.xml
+++ b/hapi-fhir-structures-dstu2/pom.xml
@@ -9,7 +9,7 @@
hapi-fhir-structures-dstu2
- jar
+ bundle
HAPI FHIR Structures - DSTU2 (FHIR v1.0.0)
@@ -361,6 +361,22 @@
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+ javax.servlet*;resolution:=optional,
+ *
+
+
+
+
diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml
index f3aa9371780..16fa0e46660 100644
--- a/hapi-fhir-structures-dstu3/pom.xml
+++ b/hapi-fhir-structures-dstu3/pom.xml
@@ -10,7 +10,7 @@
hapi-fhir-structures-dstu3
- jar
+ bundle
HAPI FHIR Structures - DSTU3
@@ -28,6 +28,18 @@
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
org.jacoco
jacoco-maven-plugin
@@ -272,5 +284,4 @@
test
-
diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml
index 2391a4c7341..75bd63e6a43 100644
--- a/hapi-fhir-structures-hl7org-dstu2/pom.xml
+++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml
@@ -10,7 +10,7 @@
hapi-fhir-structures-hl7org-dstu2
- jar
+ bundle
HAPI FHIR Structures - HL7.org DSTU2
@@ -272,6 +272,22 @@
true
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+ javax.servlet*;resolution:=optional,
+ *
+
+
+
+
diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml
index 819b6e9446c..93a32d9067c 100644
--- a/hapi-fhir-structures-r4/pom.xml
+++ b/hapi-fhir-structures-r4/pom.xml
@@ -1,5 +1,5 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
@@ -10,7 +10,7 @@
hapi-fhir-structures-r4
- jar
+ bundle
HAPI FHIR Structures - FHIR R4
@@ -29,16 +29,16 @@
-
- org.codehaus.woodstox
- woodstox-core-asl
- test
-
+
+ org.codehaus.woodstox
+ woodstox-core-asl
+ test
+
es.nitaur.markdown
txtmark
true
-
+
org.antlr
ST4
@@ -49,7 +49,7 @@
xpp3
true
-
+
@@ -262,6 +262,18 @@
true
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
diff --git a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java
index 120e25e8567..9e9637ca980 100644
--- a/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java
+++ b/hapi-fhir-structures-r4/src/main/java/org/hl7/fhir/r4/hapi/ctx/DefaultProfileValidationSupport.java
@@ -2,6 +2,7 @@ package org.hl7.fhir.r4.hapi.ctx;
import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.Charsets;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
@@ -141,27 +142,33 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
private void loadCodeSystems(FhirContext theContext, Map theCodeSystems, Map theValueSets, String theClasspath) {
ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
- InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
- if (valuesetText != null) {
- InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
+ InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
+ InputStreamReader reader = null;
+ if (inputStream != null) {
+ try {
+ reader = new InputStreamReader(inputStream, Charsets.UTF_8);
- Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
- for (BundleEntryComponent next : bundle.getEntry()) {
- if (next.getResource() instanceof CodeSystem) {
- CodeSystem nextValueSet = (CodeSystem) next.getResource();
- nextValueSet.getText().setDivAsString("");
- String system = nextValueSet.getUrl();
- if (isNotBlank(system)) {
- theCodeSystems.put(system, nextValueSet);
- }
- } else if (next.getResource() instanceof ValueSet) {
- ValueSet nextValueSet = (ValueSet) next.getResource();
- nextValueSet.getText().setDivAsString("");
- String system = nextValueSet.getUrl();
- if (isNotBlank(system)) {
- theValueSets.put(system, nextValueSet);
+ Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
+ for (BundleEntryComponent next : bundle.getEntry()) {
+ if (next.getResource() instanceof CodeSystem) {
+ CodeSystem nextValueSet = (CodeSystem) next.getResource();
+ nextValueSet.getText().setDivAsString("");
+ String system = nextValueSet.getUrl();
+ if (isNotBlank(system)) {
+ theCodeSystems.put(system, nextValueSet);
+ }
+ } else if (next.getResource() instanceof ValueSet) {
+ ValueSet nextValueSet = (ValueSet) next.getResource();
+ nextValueSet.getText().setDivAsString("");
+ String system = nextValueSet.getUrl();
+ if (isNotBlank(system)) {
+ theValueSets.put(system, nextValueSet);
+ }
}
}
+ } finally {
+ IOUtils.closeQuietly(reader);
+ IOUtils.closeQuietly(inputStream);
}
} else {
ourLog.warn("Unable to load resource: {}", theClasspath);
diff --git a/hapi-fhir-utilities/pom.xml b/hapi-fhir-utilities/pom.xml
index 46ea5d99fed..c800404caba 100644
--- a/hapi-fhir-utilities/pom.xml
+++ b/hapi-fhir-utilities/pom.xml
@@ -10,7 +10,7 @@
hapi-fhir-utilities
- jar
+ bundle
HAPI FHIR - Utilities
@@ -122,6 +122,11 @@
true
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml
index a239c743c2f..2778252ee29 100644
--- a/hapi-fhir-validation-resources-dstu2.1/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml
@@ -9,7 +9,7 @@
hapi-fhir-validation-resources-dstu2.1
- jar
+ bundle
HAPI FHIR - Validation Resources DSTU2.1 (2016May)
@@ -20,6 +20,20 @@
false
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
+
diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml
index 0f880deb8a5..2ffcd1a5102 100644
--- a/hapi-fhir-validation-resources-dstu2/pom.xml
+++ b/hapi-fhir-validation-resources-dstu2/pom.xml
@@ -9,7 +9,7 @@
hapi-fhir-validation-resources-dstu2
- jar
+ bundle
HAPI FHIR - Validation Resources (DSTU2)
@@ -20,6 +20,20 @@
false
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
+
diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml
index 01350d1b933..a313bad15e5 100644
--- a/hapi-fhir-validation-resources-dstu3/pom.xml
+++ b/hapi-fhir-validation-resources-dstu3/pom.xml
@@ -9,7 +9,7 @@
hapi-fhir-validation-resources-dstu3
- jar
+ bundle
HAPI FHIR - Validation Resources (DSTU3)
@@ -34,6 +34,20 @@
false
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
+
diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml
index 8ff27c60b26..d6c899f1941 100644
--- a/hapi-fhir-validation-resources-r4/pom.xml
+++ b/hapi-fhir-validation-resources-r4/pom.xml
@@ -9,7 +9,7 @@
hapi-fhir-validation-resources-r4
- jar
+ bundle
HAPI FHIR - Validation Resources (FHIR R4)
@@ -34,6 +34,20 @@
false
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
+
diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml
index e2e0acb930a..2f3b937bc2d 100644
--- a/hapi-fhir-validation/pom.xml
+++ b/hapi-fhir-validation/pom.xml
@@ -10,7 +10,7 @@
hapi-fhir-validation
- jar
+ bundle
HAPI FHIR - Validation
@@ -246,6 +246,18 @@
true
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+
+ ca.uhn.hapi.fhir.hapi-fhir-base
+
+
+
+
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java
index 70ff35e57b1..8bcc81dde0e 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/dstu3/hapi/validation/DefaultProfileValidationSupport.java
@@ -2,7 +2,7 @@ package org.hl7.fhir.dstu3.hapi.validation;
import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.Charsets;
-import org.apache.commons.lang.WordUtils;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
@@ -24,243 +24,249 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class DefaultProfileValidationSupport implements IValidationSupport {
- private static final String URL_PREFIX_VALUE_SET = "http://hl7.org/fhir/ValueSet/";
- private static final String URL_PREFIX_STRUCTURE_DEFINITION = "http://hl7.org/fhir/StructureDefinition/";
- private static final String URL_PREFIX_STRUCTURE_DEFINITION_BASE = "http://hl7.org/fhir/";
+ private static final String URL_PREFIX_VALUE_SET = "http://hl7.org/fhir/ValueSet/";
+ private static final String URL_PREFIX_STRUCTURE_DEFINITION = "http://hl7.org/fhir/StructureDefinition/";
+ private static final String URL_PREFIX_STRUCTURE_DEFINITION_BASE = "http://hl7.org/fhir/";
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DefaultProfileValidationSupport.class);
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DefaultProfileValidationSupport.class);
- private Map myCodeSystems;
- private Map myStructureDefinitions;
- private Map myValueSets;
+ private Map myCodeSystems;
+ private Map myStructureDefinitions;
+ private Map myValueSets;
- @Override
- public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
- ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
+ @Override
+ public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
+ ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
- Set wantCodes = new HashSet();
- for (ConceptReferenceComponent next : theInclude.getConcept()) {
- wantCodes.add(next.getCode());
- }
+ Set wantCodes = new HashSet<>();
+ for (ConceptReferenceComponent next : theInclude.getConcept()) {
+ wantCodes.add(next.getCode());
+ }
- CodeSystem system = fetchCodeSystem(theContext, theInclude.getSystem());
- for (ConceptDefinitionComponent next : system.getConcept()) {
- if (wantCodes.isEmpty() || wantCodes.contains(next.getCode())) {
- retVal.addContains().setSystem(theInclude.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
- }
- }
+ CodeSystem system = fetchCodeSystem(theContext, theInclude.getSystem());
+ for (ConceptDefinitionComponent next : system.getConcept()) {
+ if (wantCodes.isEmpty() || wantCodes.contains(next.getCode())) {
+ retVal.addContains().setSystem(theInclude.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
+ }
+ }
- return retVal;
- }
+ return retVal;
+ }
- @Override
- public List fetchAllConformanceResources(FhirContext theContext) {
- ArrayList retVal = new ArrayList<>();
- retVal.addAll(myCodeSystems.values());
- retVal.addAll(myStructureDefinitions.values());
- retVal.addAll(myValueSets.values());
- return retVal;
- }
+ @Override
+ public List fetchAllConformanceResources(FhirContext theContext) {
+ ArrayList retVal = new ArrayList<>();
+ retVal.addAll(myCodeSystems.values());
+ retVal.addAll(myStructureDefinitions.values());
+ retVal.addAll(myValueSets.values());
+ return retVal;
+ }
- @Override
- public List fetchAllStructureDefinitions(FhirContext theContext) {
- return new ArrayList(provideStructureDefinitionMap(theContext).values());
- }
+ @Override
+ public List fetchAllStructureDefinitions(FhirContext theContext) {
+ return new ArrayList(provideStructureDefinitionMap(theContext).values());
+ }
- @Override
- public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
- return (CodeSystem) fetchCodeSystemOrValueSet(theContext, theSystem, true);
- }
+ @Override
+ public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
+ return (CodeSystem) fetchCodeSystemOrValueSet(theContext, theSystem, true);
+ }
- private DomainResource fetchCodeSystemOrValueSet(FhirContext theContext, String theSystem, boolean codeSystem) {
- synchronized (this) {
- Map codeSystems = myCodeSystems;
- Map valueSets = myValueSets;
- if (codeSystems == null || valueSets == null) {
- codeSystems = new HashMap();
- valueSets = new HashMap();
+ private DomainResource fetchCodeSystemOrValueSet(FhirContext theContext, String theSystem, boolean codeSystem) {
+ synchronized (this) {
+ Map codeSystems = myCodeSystems;
+ Map valueSets = myValueSets;
+ if (codeSystems == null || valueSets == null) {
+ codeSystems = new HashMap();
+ valueSets = new HashMap();
- loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/valuesets.xml");
- loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v2-tables.xml");
- loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v3-codesystems.xml");
+ loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/valuesets.xml");
+ loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v2-tables.xml");
+ loadCodeSystems(theContext, codeSystems, valueSets, "/org/hl7/fhir/dstu3/model/valueset/v3-codesystems.xml");
- myCodeSystems = codeSystems;
- myValueSets = valueSets;
- }
+ myCodeSystems = codeSystems;
+ myValueSets = valueSets;
+ }
- if (codeSystem) {
- return codeSystems.get(theSystem);
- } else {
- return valueSets.get(theSystem);
- }
- }
- }
+ if (codeSystem) {
+ return codeSystems.get(theSystem);
+ } else {
+ return valueSets.get(theSystem);
+ }
+ }
+ }
- @SuppressWarnings("unchecked")
- @Override
- public T fetchResource(FhirContext theContext, Class theClass, String theUri) {
- Validate.notBlank(theUri, "theUri must not be null or blank");
+ @SuppressWarnings("unchecked")
+ @Override
+ public T fetchResource(FhirContext theContext, Class theClass, String theUri) {
+ Validate.notBlank(theUri, "theUri must not be null or blank");
- if (theClass.equals(StructureDefinition.class)) {
- return (T) fetchStructureDefinition(theContext, theUri);
- }
+ if (theClass.equals(StructureDefinition.class)) {
+ return (T) fetchStructureDefinition(theContext, theUri);
+ }
- if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
- return (T) fetchValueSet(theContext, theUri);
- }
+ if (theClass.equals(ValueSet.class) || theUri.startsWith(URL_PREFIX_VALUE_SET)) {
+ return (T) fetchValueSet(theContext, theUri);
+ }
- return null;
- }
+ return null;
+ }
- @Override
- public StructureDefinition fetchStructureDefinition(FhirContext theContext, String theUrl) {
- String url = theUrl;
- if (url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
- // no change
- } else if (url.indexOf('/') == -1) {
- url = URL_PREFIX_STRUCTURE_DEFINITION + url;
- } else if (StringUtils.countMatches(url, '/') == 1) {
- url = URL_PREFIX_STRUCTURE_DEFINITION_BASE + url;
- }
- Map map = provideStructureDefinitionMap(theContext);
- StructureDefinition retVal = map.get(url);
+ @Override
+ public StructureDefinition fetchStructureDefinition(FhirContext theContext, String theUrl) {
+ String url = theUrl;
+ if (url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
+ // no change
+ } else if (url.indexOf('/') == -1) {
+ url = URL_PREFIX_STRUCTURE_DEFINITION + url;
+ } else if (StringUtils.countMatches(url, '/') == 1) {
+ url = URL_PREFIX_STRUCTURE_DEFINITION_BASE + url;
+ }
+ Map map = provideStructureDefinitionMap(theContext);
+ StructureDefinition retVal = map.get(url);
- if (retVal == null && url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
- String tryUrl = URL_PREFIX_STRUCTURE_DEFINITION + StringUtils.capitalize(url.substring(URL_PREFIX_STRUCTURE_DEFINITION.length()));
- retVal = map.get(tryUrl);
- }
+ if (retVal == null && url.startsWith(URL_PREFIX_STRUCTURE_DEFINITION)) {
+ String tryUrl = URL_PREFIX_STRUCTURE_DEFINITION + StringUtils.capitalize(url.substring(URL_PREFIX_STRUCTURE_DEFINITION.length()));
+ retVal = map.get(tryUrl);
+ }
- return retVal;
- }
+ return retVal;
+ }
- ValueSet fetchValueSet(FhirContext theContext, String theSystem) {
- return (ValueSet) fetchCodeSystemOrValueSet(theContext, theSystem, false);
- }
+ ValueSet fetchValueSet(FhirContext theContext, String theSystem) {
+ return (ValueSet) fetchCodeSystemOrValueSet(theContext, theSystem, false);
+ }
- public void flush() {
- myCodeSystems = null;
- myStructureDefinitions = null;
- }
+ public void flush() {
+ myCodeSystems = null;
+ myStructureDefinitions = null;
+ }
- @Override
- public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
- CodeSystem cs = fetchCodeSystem(theContext, theSystem);
- return cs != null && cs.getContent() != CodeSystemContentMode.NOTPRESENT;
- }
+ @Override
+ public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
+ CodeSystem cs = fetchCodeSystem(theContext, theSystem);
+ return cs != null && cs.getContent() != CodeSystemContentMode.NOTPRESENT;
+ }
- private void loadCodeSystems(FhirContext theContext, Map theCodeSystems, Map theValueSets, String theClasspath) {
- ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
- InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
- if (valuesetText != null) {
- InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
+ private void loadCodeSystems(FhirContext theContext, Map theCodeSystems, Map theValueSets, String theClasspath) {
+ ourLog.info("Loading CodeSystem/ValueSet from classpath: {}", theClasspath);
+ InputStream inputStream = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
+ InputStreamReader reader = null;
+ if (inputStream != null) {
+ try {
+ reader = new InputStreamReader(inputStream, Charsets.UTF_8);
- Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
- for (BundleEntryComponent next : bundle.getEntry()) {
- if (next.getResource() instanceof CodeSystem) {
- CodeSystem nextValueSet = (CodeSystem) next.getResource();
- nextValueSet.getText().setDivAsString("");
- String system = nextValueSet.getUrl();
- if (isNotBlank(system)) {
- theCodeSystems.put(system, nextValueSet);
- }
- } else if (next.getResource() instanceof ValueSet) {
- ValueSet nextValueSet = (ValueSet) next.getResource();
- nextValueSet.getText().setDivAsString("");
- String system = nextValueSet.getUrl();
- if (isNotBlank(system)) {
- theValueSets.put(system, nextValueSet);
- }
- }
- }
- } else {
- ourLog.warn("Unable to load resource: {}", theClasspath);
- }
- }
+ Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
+ for (BundleEntryComponent next : bundle.getEntry()) {
+ if (next.getResource() instanceof CodeSystem) {
+ CodeSystem nextValueSet = (CodeSystem) next.getResource();
+ nextValueSet.getText().setDivAsString("");
+ String system = nextValueSet.getUrl();
+ if (isNotBlank(system)) {
+ theCodeSystems.put(system, nextValueSet);
+ }
+ } else if (next.getResource() instanceof ValueSet) {
+ ValueSet nextValueSet = (ValueSet) next.getResource();
+ nextValueSet.getText().setDivAsString("");
+ String system = nextValueSet.getUrl();
+ if (isNotBlank(system)) {
+ theValueSets.put(system, nextValueSet);
+ }
+ }
+ }
+ } finally {
+ IOUtils.closeQuietly(reader);
+ IOUtils.closeQuietly(inputStream);
+ }
+ } else {
+ ourLog.warn("Unable to load resource: {}", theClasspath);
+ }
+ }
- private void loadStructureDefinitions(FhirContext theContext, Map theCodeSystems, String theClasspath) {
- ourLog.info("Loading structure definitions from classpath: {}", theClasspath);
- InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
- if (valuesetText != null) {
- InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
+ private void loadStructureDefinitions(FhirContext theContext, Map theCodeSystems, String theClasspath) {
+ ourLog.info("Loading structure definitions from classpath: {}", theClasspath);
+ InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theClasspath);
+ if (valuesetText != null) {
+ InputStreamReader reader = new InputStreamReader(valuesetText, Charsets.UTF_8);
- Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
- for (BundleEntryComponent next : bundle.getEntry()) {
- if (next.getResource() instanceof StructureDefinition) {
- StructureDefinition nextSd = (StructureDefinition) next.getResource();
- nextSd.getText().setDivAsString("");
- String system = nextSd.getUrl();
- if (isNotBlank(system)) {
- theCodeSystems.put(system, nextSd);
- }
- }
- }
- } else {
- ourLog.warn("Unable to load resource: {}", theClasspath);
- }
- }
+ Bundle bundle = theContext.newXmlParser().parseResource(Bundle.class, reader);
+ for (BundleEntryComponent next : bundle.getEntry()) {
+ if (next.getResource() instanceof StructureDefinition) {
+ StructureDefinition nextSd = (StructureDefinition) next.getResource();
+ nextSd.getText().setDivAsString("");
+ String system = nextSd.getUrl();
+ if (isNotBlank(system)) {
+ theCodeSystems.put(system, nextSd);
+ }
+ }
+ }
+ } else {
+ ourLog.warn("Unable to load resource: {}", theClasspath);
+ }
+ }
- private Map provideStructureDefinitionMap(FhirContext theContext) {
- Map structureDefinitions = myStructureDefinitions;
- if (structureDefinitions == null) {
- structureDefinitions = new HashMap();
+ private Map provideStructureDefinitionMap(FhirContext theContext) {
+ Map structureDefinitions = myStructureDefinitions;
+ if (structureDefinitions == null) {
+ structureDefinitions = new HashMap();
- loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-resources.xml");
- loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-types.xml");
- loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-others.xml");
+ loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-resources.xml");
+ loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-types.xml");
+ loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/dstu3/model/profile/profiles-others.xml");
- myStructureDefinitions = structureDefinitions;
- }
- return structureDefinitions;
- }
+ myStructureDefinitions = structureDefinitions;
+ }
+ return structureDefinitions;
+ }
- private CodeValidationResult testIfConceptIsInList(String theCode, List conceptList, boolean theCaseSensitive) {
- String code = theCode;
- if (theCaseSensitive == false) {
- code = code.toUpperCase();
- }
+ private CodeValidationResult testIfConceptIsInList(String theCode, List conceptList, boolean theCaseSensitive) {
+ String code = theCode;
+ if (theCaseSensitive == false) {
+ code = code.toUpperCase();
+ }
- return testIfConceptIsInListInner(conceptList, theCaseSensitive, code);
- }
+ return testIfConceptIsInListInner(conceptList, theCaseSensitive, code);
+ }
- private CodeValidationResult testIfConceptIsInListInner(List conceptList, boolean theCaseSensitive, String code) {
- CodeValidationResult retVal = null;
- for (ConceptDefinitionComponent next : conceptList) {
- String nextCandidate = next.getCode();
- if (theCaseSensitive == false) {
- nextCandidate = nextCandidate.toUpperCase();
- }
- if (nextCandidate.equals(code)) {
- retVal = new CodeValidationResult(next);
- break;
- }
+ private CodeValidationResult testIfConceptIsInListInner(List conceptList, boolean theCaseSensitive, String code) {
+ CodeValidationResult retVal = null;
+ for (ConceptDefinitionComponent next : conceptList) {
+ String nextCandidate = next.getCode();
+ if (theCaseSensitive == false) {
+ nextCandidate = nextCandidate.toUpperCase();
+ }
+ if (nextCandidate.equals(code)) {
+ retVal = new CodeValidationResult(next);
+ break;
+ }
- // recurse
- retVal = testIfConceptIsInList(code, next.getConcept(), theCaseSensitive);
- if (retVal != null) {
- break;
- }
- }
+ // recurse
+ retVal = testIfConceptIsInList(code, next.getConcept(), theCaseSensitive);
+ if (retVal != null) {
+ break;
+ }
+ }
- return retVal;
- }
+ return retVal;
+ }
- @Override
- public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
- CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
- if (cs != null) {
- boolean caseSensitive = true;
- if (cs.hasCaseSensitive()) {
- caseSensitive = cs.getCaseSensitive();
- }
+ @Override
+ public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
+ CodeSystem cs = fetchCodeSystem(theContext, theCodeSystem);
+ if (cs != null) {
+ boolean caseSensitive = true;
+ if (cs.hasCaseSensitive()) {
+ caseSensitive = cs.getCaseSensitive();
+ }
- CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
+ CodeValidationResult retVal = testIfConceptIsInList(theCode, cs.getConcept(), caseSensitive);
- if (retVal != null) {
- return retVal;
- }
- }
+ if (retVal != null) {
+ return retVal;
+ }
+ }
- return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
- }
+ return new CodeValidationResult(IssueSeverity.WARNING, "Unknown code: " + theCodeSystem + " / " + theCode);
+ }
}
diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/DefaultProfileValidationSupport.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/DefaultProfileValidationSupport.java
index 24dcf7945a1..0523b22963c 100644
--- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/DefaultProfileValidationSupport.java
+++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/instance/hapi/validation/DefaultProfileValidationSupport.java
@@ -2,6 +2,7 @@ package org.hl7.fhir.instance.hapi.validation;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.Bundle;
import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.instance.model.CodeType;
@@ -44,9 +45,9 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
if (valueSets == null) {
valueSets = new HashMap();
- loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/valuesets.xml");
- loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v2-tables.xml");
- loadCodeSystems(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v3-codesystems.xml");
+ loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/valuesets.xml");
+ loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v2-tables.xml");
+ loadValueSets(theContext, valueSets, "/org/hl7/fhir/instance/model/valueset/v3-codesystems.xml");
myCodeSystems = valueSets;
}
@@ -108,26 +109,34 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
return false;
}
- private void loadCodeSystems(FhirContext theContext, Map codeSystems, String file) {
- InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(file);
- if (valuesetText != null) {
- InputStreamReader reader;
- try {
- reader = new InputStreamReader(valuesetText, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- // Shouldn't happen!
- throw new InternalErrorException("UTF-8 encoding not supported on this platform", e);
- }
+ private void loadValueSets(FhirContext theContext, Map theValueSets, String theFile) {
+ InputStream valuesetText = DefaultProfileValidationSupport.class.getResourceAsStream(theFile);
+ try {
+ if (valuesetText != null) {
+ InputStreamReader reader = null;
+ try {
+ reader = new InputStreamReader(valuesetText, "UTF-8");
- FhirContext ctx = FhirInstanceValidator.getHl7OrgDstu2Ctx(theContext);
- Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, reader);
- for (BundleEntryComponent next : bundle.getEntry()) {
- ValueSet nextValueSet = (ValueSet) next.getResource();
- String system = nextValueSet.getCodeSystem().getSystem();
- if (isNotBlank(system)) {
- codeSystems.put(system, nextValueSet);
+ FhirContext ctx = FhirInstanceValidator.getHl7OrgDstu2Ctx(theContext);
+ Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, reader);
+ for (BundleEntryComponent next : bundle.getEntry()) {
+ ValueSet nextValueSet = (ValueSet) next.getResource();
+ String system = nextValueSet.getCodeSystem().getSystem();
+ if (isNotBlank(system)) {
+ theValueSets.put(system, nextValueSet);
+ }
+ }
+
+ } catch (UnsupportedEncodingException e) {
+ // Shouldn't happen!
+ throw new InternalErrorException("UTF-8 encoding not supported on this platform", e);
+ } finally {
+ IOUtils.closeQuietly(reader);
}
+
}
+ } finally {
+ IOUtils.closeQuietly(valuesetText);
}
}
@@ -136,7 +145,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
ValueSet vs = fetchCodeSystem(theContext, theCodeSystem);
if (vs != null) {
for (ValueSet.ConceptDefinitionComponent nextConcept : vs.getCodeSystem().getConcept()) {
- if (nextConcept.getCode().equals(theCode)){
+ if (nextConcept.getCode().equals(theCode)) {
ValueSet.ConceptDefinitionComponent component = new ValueSet.ConceptDefinitionComponent(new CodeType(theCode));
return new CodeValidationResult(component);
}
diff --git a/osgi/hapi-fhir-karaf-features/pom.xml b/osgi/hapi-fhir-karaf-features/pom.xml
new file mode 100644
index 00000000000..9f3ead87c96
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-features/pom.xml
@@ -0,0 +1,218 @@
+
+
+ 4.0.0
+
+
+ ca.uhn.hapi.fhir
+ hapi-deployable-pom
+ 3.3.0-SNAPSHOT
+ ../../hapi-deployable-pom/pom.xml
+
+
+ ca.uhn.hapi.fhir.karaf
+ hapi-fhir
+ pom
+ HAPI FHIR - Apache Karaf :: Features
+
+
+ features.xml
+ 1.8.6
+ 3.2.2
+
+
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-base
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-dstu2
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-dstu2.1
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-hl7org-dstu2
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-dstu3
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-r4
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-dstu3
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-dstu2
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-dstu2.1
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-r4
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-converter
+ ${project.version}
+
+
+
+
+ org.osgi
+ org.osgi.core
+ 4.3.1
+ provided
+
+
+ org.ops4j.pax.logging
+ pax-logging-api
+ ${pax-logging-version}
+ provided
+
+
+ org.ops4j.pax.logging
+ pax-logging-service
+ ${pax-logging-version}
+ provided
+
+
+ org.apache.felix
+ org.apache.felix.framework
+ ${felix-framework-version}
+ provided
+
+
+ org.apache.felix
+ org.apache.felix.configadmin
+ 1.8.8
+ provided
+
+
+ org.apache.aries.blueprint
+ org.apache.aries.blueprint.api
+ 1.0.1
+ provided
+
+
+ org.apache.aries.blueprint
+ org.apache.aries.blueprint.core
+ 1.0.1
+ provided
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.core
+ ${apache_karaf_version}
+ provided
+
+
+ org.apache.karaf.features
+ framework
+ ${apache_karaf_version}
+ kar
+ provided
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.0.2
+
+
+ filter
+ generate-resources
+
+ resources
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ attach-artifacts
+ package
+
+ attach-artifact
+
+
+
+
+ target/classes/features.xml
+ xml
+ features
+
+
+
+
+
+
+
+ org.apache.karaf.tooling
+ karaf-maven-plugin
+ ${apache_karaf_version}
+
+
+ file://${project.build.directory}/classes/${features.file}
+ mvn:org.apache.karaf.features/enterprise/${apache_karaf_version}/xml/features
+
+ org.apache.karaf.features:framework
+ 1.8
+
+ framework
+
+
+ hapi-fhir*
+
+
+
+
+ validate
+ process-resources
+
+ verify
+
+
+
+
+
+
+
diff --git a/osgi/hapi-fhir-karaf-features/src/main/resources/features.xml b/osgi/hapi-fhir-karaf-features/src/main/resources/features.xml
new file mode 100644
index 00000000000..8d844b054f4
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-features/src/main/resources/features.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+ wrap
+ mvn:com.google.code.gson/gson/${gson_version}
+ mvn:org.apache.commons/commons-lang3/${commons_lang3_version}
+ mvn:commons-codec/commons-codec/${commons_codec_version}
+ mvn:commons-io/commons-io/${commons_io_version}
+ mvn:com.google.guava/guava/${guava_version}
+ wrap:mvn:com.google.errorprone/error_prone_annotations/${error_prone_annotations_version}
+ mvn:org.codehaus.woodstox/stax2-api/${stax2_api_version}
+ mvn:org.codehaus.woodstox/woodstox-core-asl/${woodstox_core_asl_version}
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-base/${project.version}
+
+
+
+ hapi-fhir
+ mvn:org.apache.httpcomponents/httpcore-osgi/${httpcore_version}
+ mvn:org.apache.httpcomponents/httpclient-osgi/${httpclient_version}
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-client/${project.version}
+
+
+
+ hapi-fhir
+ mvn:com.google.code.gson/gson/${gson_version}
+ mvn:commons-codec/commons-codec/${commons_codec_version}
+ mvn:commons-io/commons-io/${commons_io_version}
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-utilities/${project.version}
+
+
+
+ hapi-fhir
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-dstu2/${project.version}
+
+
+
+ hapi-fhir
+ hapi-fhir-utilities
+
+ mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.saxon/${servicemix_saxon_version}
+
+
+ mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/${servicemix_xmlresolver_version}
+
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-hl7org-dstu2/${project.version}
+
+
+
+ hapi-fhir
+ hapi-fhir-utilities
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-dstu2.1/${project.version}
+
+
+
+ hapi-fhir
+ hapi-fhir-utilities
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-dstu3/${project.version}
+
+
+
+ hapi-fhir
+ hapi-fhir-utilities
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-structures-r4/${project.version}
+
+
+
+
+ mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.saxon/${servicemix_saxon_version}
+
+
+ mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/${servicemix_xmlresolver_version}
+
+ mvn:com.google.code.findbugs/jsr305/${jsr305_version}
+ mvn:com.phloc/phloc-schematron/${phloc_schematron_version}
+ mvn:com.phloc/phloc-commons/${phloc_commons_version}
+
+
+
+ hapi-fhir
+ hapi-fhir-utilities
+ hapi-fhir-ph-schematron
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-converter/${project.version}
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-validation/${project.version}
+
+
+
+ hapi-fhir-validation
+ hapi-fhir-dstu2
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu2/${project.version}
+
+
+
+ hapi-fhir-validation
+ hapi-fhir-hl7org-dstu2
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu2/${project.version}
+
+
+
+ hapi-fhir-validation
+ hapi-fhir-dstu2.1
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu2.1/${project.version}
+
+
+
+ hapi-fhir-validation
+ hapi-fhir-dstu3
+ hapi-fhir-r4
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-dstu3/${project.version}
+
+
+
+ hapi-fhir-validation
+ hapi-fhir-r4
+ mvn:ca.uhn.hapi.fhir/hapi-fhir-validation-resources-r4/${project.version}
+
+
diff --git a/osgi/hapi-fhir-karaf-integration-tests/pom.xml b/osgi/hapi-fhir-karaf-integration-tests/pom.xml
new file mode 100644
index 00000000000..22cab824417
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/pom.xml
@@ -0,0 +1,181 @@
+
+
+ 4.0.0
+
+
+ ca.uhn.hapi.fhir
+ hapi-deployable-pom
+ 3.3.0-SNAPSHOT
+ ../../hapi-deployable-pom/pom.xml
+
+
+ hapi-fhir-karaf-integration-tests
+ jar
+ HAPI-FHIR Apache Karaf Integration Tests
+
+
+ Integration tests for the HAPI-FHIR Apache Karaf features
+
+
+
+ 4.9.1
+
+
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-base
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-client
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-dstu2
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-dstu2.1
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-hl7org-dstu2
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-dstu3
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-structures-r4
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-dstu3
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-dstu2
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-dstu2.1
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation-resources-r4
+ ${project.version}
+
+
+ ca.uhn.hapi.fhir
+ hapi-fhir-validation
+ ${project.version}
+
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-container-karaf
+ ${pax.exam.version}
+ test
+
+
+ org.ops4j.pax.exam
+ pax-exam-junit4
+ ${pax.exam.version}
+ test
+
+
+ org.xmlunit
+ xmlunit-core
+ test
+
+
+ org.apache.karaf
+ apache-karaf
+ ${apache_karaf_version}
+ test
+ tar.gz
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.console
+ ${apache_karaf_version}
+ test
+
+
+ ca.uhn.hapi.fhir.karaf
+ hapi-fhir
+ ${project.version}
+ features
+ xml
+ test
+
+
+ org.apache.karaf.features
+ enterprise
+ ${apache_karaf_version}
+ features
+ xml
+ test
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.hamcrest
+ 1.3_1
+ runtime
+
+
+
+
+
+
+ org.apache.servicemix.tooling
+ depends-maven-plugin
+ 1.2
+
+
+ generate-depends-file
+
+ generate-depends-file
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ 1
+ false
+
+
+
+
+
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/PaxExamOptions.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/PaxExamOptions.java
new file mode 100644
index 00000000000..fd73eb00156
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/PaxExamOptions.java
@@ -0,0 +1,142 @@
+package ca.uhn.fhir.tests.integration.karaf;
+
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+
+import java.io.File;
+
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
+
+public enum PaxExamOptions {
+ KARAF(
+ karafDistributionConfiguration()
+ .frameworkUrl(
+ maven()
+ .groupId("org.apache.karaf")
+ .artifactId("apache-karaf")
+ .versionAsInProject()
+ .type("zip"))
+ .name("Apache Karaf")
+ .useDeployFolder(false)
+ .unpackDirectory(new File("target/paxexam/unpack/")),
+ keepRuntimeFolder(),
+ configureConsole().ignoreLocalConsole(),
+ logLevel(LogLevelOption.LogLevel.INFO)
+ ),
+ WRAP(
+ features(
+ maven()
+ .groupId("org.apache.karaf.features")
+ .artifactId("enterprise")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "wrap")
+ ),
+ HAPI_FHIR_CLIENT(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-client")
+ ),
+ HAPI_FHIR_HL7ORG_DSTU2(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-hl7org-dstu2")
+ ),
+ HAPI_FHIR_DSTU2_1(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-dstu2.1")
+ ),
+ HAPI_FHIR_DSTU3(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-dstu3")
+ ),
+ HAPI_FHIR_R4(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-r4")
+ ),
+ HAPI_FHIR_VALIDATION_DSTU2(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-validation-dstu2")
+ ),
+ HAPI_FHIR_VALIDATION_HL7ORG_DSTU2(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-validation-hl7org-dstu2")
+ ),
+ HAPI_FHIR_VALIDATION_DSTU3(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-validation-dstu3")
+ ),
+ HAPI_FHIR_VALIDATION_R4(
+ features(
+ maven()
+ .groupId("ca.uhn.hapi.fhir.karaf")
+ .artifactId("hapi-fhir")
+ .type("xml")
+ .classifier("features")
+ .versionAsInProject(),
+ "hapi-fhir-validation-r4")
+ );
+
+ private final Option[] options;
+
+ PaxExamOptions(Option... options) {
+ this.options = options;
+ }
+
+ public Option option() {
+ return new DefaultCompositeOption(options);
+ }
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/client/FhirClientTest.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/client/FhirClientTest.java
new file mode 100644
index 00000000000..55e3a507524
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/client/FhirClientTest.java
@@ -0,0 +1,63 @@
+package ca.uhn.fhir.tests.integration.karaf.client;
+
+import java.io.IOException;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.api.MethodOutcome;
+import ca.uhn.fhir.rest.api.PreferReturnEnum;
+import ca.uhn.fhir.rest.client.api.IGenericClient;
+import org.hl7.fhir.dstu3.model.Patient;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_CLIENT;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_DSTU3;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+
+/**
+ * Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+@Ignore(value = "Relies on external service being up and running")
+public class FhirClientTest {
+
+ private FhirContext fhirContext = FhirContext.forDstu3();
+ private IGenericClient client = fhirContext.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu3");
+ private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirClientTest.class);
+
+ @Configuration
+ public Option[] config() throws IOException {
+ return options(
+ KARAF.option(),
+ HAPI_FHIR_CLIENT.option(),
+ HAPI_FHIR_DSTU3.option(),
+ mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
+ WRAP.option(),
+ when(false)
+ .useOptions(
+ debugConfiguration("5005", true))
+ );
+ }
+
+ @Test
+ public void createPatient() throws Exception {
+ Patient patient = new Patient();
+ patient.setId("PATIENTID");
+ patient.getMeta().addProfile("http://BAR");
+ patient.addName().addGiven("GIVEN");
+ MethodOutcome execute = client.create().resource(patient).prefer(PreferReturnEnum.REPRESENTATION).execute();
+ ourLog.info(execute.toString());
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2/Dstu2ResourceValidatorDstu2Test.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2/Dstu2ResourceValidatorDstu2Test.java
new file mode 100644
index 00000000000..ff2cc52a836
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2/Dstu2ResourceValidatorDstu2Test.java
@@ -0,0 +1,331 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.model.api.ExtensionDt;
+import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
+import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
+import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
+import ca.uhn.fhir.model.dstu2.resource.Bundle;
+import ca.uhn.fhir.model.dstu2.resource.Condition;
+import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
+import ca.uhn.fhir.model.dstu2.resource.Patient;
+import ca.uhn.fhir.model.dstu2.valueset.ConditionVerificationStatusEnum;
+import ca.uhn.fhir.model.dstu2.valueset.NarrativeStatusEnum;
+import ca.uhn.fhir.model.primitive.DateDt;
+import ca.uhn.fhir.model.primitive.InstantDt;
+import ca.uhn.fhir.model.primitive.StringDt;
+import ca.uhn.fhir.parser.DataFormatException;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.parser.StrictErrorHandler;
+import ca.uhn.fhir.validation.FhirValidator;
+import ca.uhn.fhir.validation.SchemaBaseValidator;
+import ca.uhn.fhir.validation.ValidationFailureException;
+import ca.uhn.fhir.validation.ValidationResult;
+import ca.uhn.fhir.validation.schematron.SchematronBaseValidator;
+import org.apache.commons.io.IOUtils;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.core.StringContains;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_VALIDATION_DSTU2;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+
+
+/**
+ * Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class Dstu2ResourceValidatorDstu2Test {
+
+ private FhirContext ourCtx = FhirContext.forDstu2();
+ private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Dstu2ResourceValidatorDstu2Test.class);
+
+ @Configuration
+ public Option[] config() throws IOException {
+ return options(
+ KARAF.option(),
+ WRAP.option(),
+ HAPI_FHIR_VALIDATION_DSTU2.option(),
+ mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
+ when(false)
+ .useOptions(
+ debugConfiguration("5005", true))
+ );
+ }
+
+ private FhirValidator createFhirValidator() {
+ FhirValidator val = ourCtx.newValidator();
+ val.setValidateAgainstStandardSchema(true);
+ val.setValidateAgainstStandardSchematron(true);
+ return val;
+ }
+
+ private String logOperationOutcome(ValidationResult result) {
+ OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome);
+ ourLog.info(encoded);
+ return encoded;
+ }
+
+ /**
+ * See issue #50
+ */
+ @Test()
+ public void testOutOfBoundsDate() {
+ Patient p = new Patient();
+ p.setBirthDate(new DateDt("2000-12-31"));
+
+ // Put in an invalid date
+ IParser parser = ourCtx.newXmlParser();
+ parser.setParserErrorHandler(new StrictErrorHandler());
+
+ String encoded = parser.setPrettyPrint(true).encodeResourceToString(p).replace("2000-12-31", "2000-15-31");
+ ourLog.info(encoded);
+
+ assertThat(encoded, StringContains.containsString("2000-15-31"));
+
+ ValidationResult result = ourCtx.newValidator().validateWithResult(encoded);
+ String resultString = parser.setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
+ ourLog.info(resultString);
+
+ assertEquals(2, ((OperationOutcome)result.toOperationOutcome()).getIssue().size());
+ assertThat(resultString, StringContains.containsString("cvc-pattern-valid"));
+
+ try {
+ parser.parseResource(encoded);
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Invalid attribute value \"2000-15-31\": Invalid date/time format: \"2000-15-31\"", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testSchemaBundleValidatorIsSuccessful() throws IOException {
+ String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("bundle-example.json"), StandardCharsets.UTF_8);
+ Bundle b = ourCtx.newJsonParser().parseResource(Bundle.class, res);
+
+ ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b));
+
+ FhirValidator val = createFhirValidator();
+
+ ValidationResult result = val.validateWithResult(b);
+
+ OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
+
+ assertTrue(result.toString(), result.isSuccessful());
+ assertNotNull(operationOutcome);
+ assertEquals(1, operationOutcome.getIssue().size());
+ }
+
+ @SuppressWarnings("deprecation")
+ @Test
+ public void testSchemaResourceValidator() throws IOException {
+ String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.json"));
+ Patient p = ourCtx.newJsonParser().parseResource(Patient.class, res);
+
+ ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p));
+
+ FhirValidator val = ourCtx.newValidator();
+ val.setValidateAgainstStandardSchema(true);
+ val.setValidateAgainstStandardSchematron(false);
+
+ val.validate(p);
+
+ p.getAnimal().getBreed().setText("The Breed");
+ try {
+ val.validate(p);
+ fail();
+ } catch (ValidationFailureException e) {
+ OperationOutcome operationOutcome = (OperationOutcome) e.getOperationOutcome();
+ ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome));
+ assertEquals(1, operationOutcome.getIssue().size());
+ assertThat(operationOutcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type"));
+ }
+ }
+
+ /**
+ * Make sure that the elements that appear in all resources (meta, language, extension, etc)
+ * all appear in the correct order
+ */
+ @Test
+ public void testValidateResourceWithResourceElements() {
+ TestPatientFor327 patient = new TestPatientFor327();
+ patient.setBirthDate(new Date(), TemporalPrecisionEnum.DAY);
+ patient.setId("123");
+ patient.getText().setDiv("FOO
");
+ patient.getText().setStatus(NarrativeStatusEnum.GENERATED);
+ patient.getLanguage().setValue("en");
+ patient.addUndeclaredExtension(true, "http://foo").setValue(new StringDt("MOD"));
+ ResourceMetadataKeyEnum.UPDATED.put(patient, new InstantDt(new Date()));
+
+ List conditions = new ArrayList();
+ Condition condition = new Condition();
+ condition.getPatient().setReference("Patient/123");
+ condition.addBodySite().setText("BODY SITE");
+ condition.getCode().setText("CODE");
+ condition.setVerificationStatus(ConditionVerificationStatusEnum.CONFIRMED);
+ conditions.add(new ResourceReferenceDt(condition));
+ patient.setCondition(conditions);
+ patient.addIdentifier().setSystem("http://foo").setValue("123");
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ FhirValidator val = createFhirValidator();
+ ValidationResult result = val.validateWithResult(encoded);
+
+ String messageString = logOperationOutcome(result);
+
+ assertTrue(result.isSuccessful());
+
+ assertThat(messageString, containsString("No issues"));
+
+ }
+
+ /**
+ * See
+ * https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium=
+ * email&utm_source=footer
+ */
+ @Test
+ public void testValidateWithExtensionsJson() {
+ PatientProfileDstu2 myPatient = new PatientProfileDstu2();
+ myPatient.setColorPrimary(new CodeableConceptDt("http://example.com#animalColor", "furry-grey"));
+ myPatient.setColorSecondary(new CodeableConceptDt("http://example.com#animalColor", "furry-white"));
+ myPatient.setOwningOrganization(new ResourceReferenceDt("Organization/2.25.79433498044103547197447759549862032393"));
+ myPatient.addName().addFamily("FamilyName");
+ myPatient.addUndeclaredExtension(new ExtensionDt().setUrl("http://foo.com/example").setValue(new StringDt("String Extension")));
+
+ IParser p = FhirContext.forDstu2().newJsonParser().setPrettyPrint(true);
+ String messageString = p.encodeResourceToString(myPatient);
+ ourLog.info(messageString);
+
+ //@formatter:off
+ assertThat(messageString, stringContainsInOrder(
+ "meta",
+ "String Extension",
+ "Organization/2.25.79433498044103547197447759549862032393",
+ "furry-grey",
+ "furry-white",
+ "FamilyName"
+ ));
+ assertThat(messageString, not(stringContainsInOrder(
+ "extension",
+ "meta"
+ )));
+ //@formatter:on
+
+ FhirValidator val = ourCtx.newValidator();
+ val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
+ val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
+
+ ValidationResult result = val.validateWithResult(messageString);
+
+ logOperationOutcome(result);
+
+ assertTrue(result.isSuccessful());
+
+ assertThat(messageString, containsString("valueReference"));
+ assertThat(messageString, not(containsString("valueResource")));
+ }
+
+ private Matcher super String> stringContainsInOrder(java.lang.String... substrings) {
+ return Matchers.stringContainsInOrder(Arrays.asList(substrings));
+ }
+
+ /**
+ * See
+ * https://groups.google.com/d/msgid/hapi-fhir/a266083f-6454-4cf0-a431-c6500f052bea%40googlegroups.com?utm_medium=
+ * email&utm_source=footer
+ */
+ @Test
+ public void testValidateWithExtensionsXml() {
+ PatientProfileDstu2 myPatient = new PatientProfileDstu2();
+ myPatient.setColorPrimary(new CodeableConceptDt("http://example.com#animalColor", "furry-grey"));
+ myPatient.setColorSecondary(new CodeableConceptDt("http://example.com#animalColor", "furry-white"));
+ myPatient.setOwningOrganization(new ResourceReferenceDt("Organization/2.25.79433498044103547197447759549862032393"));
+ myPatient.addName().addFamily("FamilyName");
+ myPatient.addUndeclaredExtension(new ExtensionDt().setUrl("http://foo.com/example").setValue(new StringDt("String Extension")));
+
+ IParser p = FhirContext.forDstu2().newXmlParser().setPrettyPrint(true);
+ String messageString = p.encodeResourceToString(myPatient);
+ ourLog.info(messageString);
+
+ //@formatter:off
+ assertThat(messageString, stringContainsInOrder(
+ "meta",
+ "Organization/2.25.79433498044103547197447759549862032393",
+ "furry-grey",
+ "furry-white",
+ "String Extension",
+ "FamilyName"
+ ));
+ assertThat(messageString, not(stringContainsInOrder(
+ "extension",
+ "meta"
+ )));
+ assertThat(messageString, containsString("url=\"http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorSecondary\""));
+ assertThat(messageString, containsString("url=\"http://foo.com/example\""));
+ //@formatter:on
+
+ FhirValidator val = ourCtx.newValidator();
+ val.registerValidatorModule(new SchemaBaseValidator(ourCtx));
+ val.registerValidatorModule(new SchematronBaseValidator(ourCtx));
+
+ ValidationResult result = val.validateWithResult(messageString);
+
+ logOperationOutcome(result);
+
+ assertTrue(result.isSuccessful());
+
+ assertThat(messageString, containsString("valueReference"));
+ assertThat(messageString, not(containsString("valueResource")));
+ }
+
+ @ResourceDef(name = "Patient")
+ public static class TestPatientFor327 extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(name = "testCondition")
+ @ca.uhn.fhir.model.api.annotation.Extension(url = "testCondition", definedLocally = true, isModifier = false)
+ private List testConditions = null;
+
+ public List getConditions() {
+ return this.testConditions;
+ }
+
+ public void setCondition(List ref) {
+ this.testConditions = ref;
+ }
+ }
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2/PatientProfileDstu2.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2/PatientProfileDstu2.java
new file mode 100644
index 00000000000..dfd33d12e46
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2/PatientProfileDstu2.java
@@ -0,0 +1,72 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2;
+
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.Description;
+import ca.uhn.fhir.model.api.annotation.Extension;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
+import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
+import ca.uhn.fhir.model.dstu2.resource.Patient;
+import ca.uhn.fhir.util.ElementUtil;
+
+@ResourceDef(name="Patient", profile = "http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient")
+public class PatientProfileDstu2 extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(name="owner", min=0, max=1)
+ @Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#owningOrganization", definedLocally=false, isModifier=false)
+ @Description(shortDefinition="The organization that owns this animal")
+ private ResourceReferenceDt owningOrganization;
+
+ public ResourceReferenceDt getOwningOrganization() {
+ if (owningOrganization == null) {
+ owningOrganization = new ResourceReferenceDt();
+ }
+ return owningOrganization;
+ }
+
+ public PatientProfileDstu2 setOwningOrganization(ResourceReferenceDt owningOrganization) {
+ this.owningOrganization = owningOrganization;
+ return this;
+ }
+
+ @Child(name="colorPrimary", min=0, max=1)
+ @Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorPrimary", definedLocally=false, isModifier=false)
+ @Description(shortDefinition="The animals primary color")
+ private CodeableConceptDt colorPrimary;
+
+ @Child(name="colorSecondary", min=0, max=1)
+ @Extension(url="http://ahr.copa.inso.tuwien.ac.at/StructureDefinition/Patient#animal-colorSecondary", definedLocally=false, isModifier=false)
+ @Description(shortDefinition="The animals secondary color")
+ private CodeableConceptDt colorSecondary;
+
+ public CodeableConceptDt getColorPrimary() {
+ if (this.colorPrimary == null) {
+ return new CodeableConceptDt();
+ }
+ return colorPrimary;
+ }
+
+ public void setColorPrimary(CodeableConceptDt colorPrimary) {
+ this.colorPrimary = colorPrimary;
+ }
+
+ public CodeableConceptDt getColorSecondary() {
+ if (this.colorSecondary == null) {
+ return new CodeableConceptDt();
+ }
+ return colorSecondary;
+ }
+
+ public void setColorSecondary(CodeableConceptDt colorSecondary) {
+ this.colorSecondary = colorSecondary;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty() && ElementUtil.isEmpty(owningOrganization) && ElementUtil.isEmpty(colorPrimary)
+ && ElementUtil.isEmpty(colorSecondary) ;
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/JsonParserDstu2_1Test.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/JsonParserDstu2_1Test.java
new file mode 100644
index 00000000000..48a48095dcf
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/JsonParserDstu2_1Test.java
@@ -0,0 +1,1438 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu21;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.UUID;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.parser.DataFormatException;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.parser.LenientErrorHandler;
+import ca.uhn.fhir.parser.StrictErrorHandler;
+import com.google.common.collect.Sets;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hl7.fhir.dstu2016may.model.Conformance;
+import org.hl7.fhir.dstu2016may.model.PrimitiveType;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_DSTU2_1;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+
+
+/**
+ * Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class JsonParserDstu2_1Test {
+
+ private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserDstu2_1Test.class);
+ private FhirContext ourCtx = FhirContext.forDstu2_1();
+
+ @Configuration
+ public Option[] config() throws IOException {
+ return options(
+ KARAF.option(),
+ WRAP.option(),
+ HAPI_FHIR_DSTU2_1.option(),
+ mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
+ when(false)
+ .useOptions(
+ debugConfiguration("5005", true))
+ );
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnFhirContext() {
+ try {
+ String tmp = "{\"resourceType\":\"Bundle\",\"entry\":[{\"fullUrl\":\"http://lalaland.org/patient/pat1\",\"resource\":{\"resourceType\":\"Patient\",\"id\":\"patxuzos\"}}]}";
+ ourCtx.getParserOptions().setOverrideResourceIdWithBundleEntryFullUrl(false);
+ org.hl7.fhir.dstu2016may.model.Bundle bundle = (org.hl7.fhir.dstu2016may.model.Bundle) ourCtx.newJsonParser().parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ org.hl7.fhir.dstu2016may.model.Patient o1 = (org.hl7.fhir.dstu2016may.model.Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ } finally {
+ // ensure we cleanup ourCtx so other tests continue to work
+ ourCtx = FhirContext.forDstu2_1();
+ }
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnParser() {
+ try {
+ String tmp = "{\"resourceType\":\"Bundle\",\"entry\":[{\"fullUrl\":\"http://lalaland.org/patient/pat1\",\"resource\":{\"resourceType\":\"Patient\",\"id\":\"patxuzos\"}}]}";
+ org.hl7.fhir.dstu2016may.model.Bundle bundle = (org.hl7.fhir.dstu2016may.model.Bundle) ourCtx.newJsonParser().setOverrideResourceIdWithBundleEntryFullUrl(false).parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ org.hl7.fhir.dstu2016may.model.Patient o1 = (org.hl7.fhir.dstu2016may.model.Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ } finally {
+ // ensure we cleanup ourCtx so other tests continue to work
+ ourCtx = FhirContext.forDstu2_1();
+ }
+ }
+
+ /**
+ * #480
+ */
+ @Test
+ public void testEncodeEmptyValue() {
+ org.hl7.fhir.dstu2016may.model.QuestionnaireResponse qr = new org.hl7.fhir.dstu2016may.model.QuestionnaireResponse();
+ qr.setId("123");
+ qr.getAuthoredElement().setValueAsString("");
+ qr.addItem().setLinkIdElement(new org.hl7.fhir.dstu2016may.model.StringType());
+ qr.getItem().get(0).addItem().setLinkIdElement(new org.hl7.fhir.dstu2016may.model.StringType(""));
+ qr.getItem().get(0).addItem().setLinkIdElement(new org.hl7.fhir.dstu2016may.model.StringType("LINKID"));
+
+ String encoded = ourCtx.newJsonParser().encodeResourceToString(qr);
+ ourLog.info(encoded);
+
+ assertThat(encoded, stringContainsInOrder("123"));
+ assertThat(encoded, not(stringContainsInOrder("\"\"")));
+ assertThat(encoded, not(stringContainsInOrder("null")));
+ }
+
+
+
+ @Test
+ public void testEncodeAndParseExtensions() throws Exception {
+
+ org.hl7.fhir.dstu2016may.model.Patient patient = new org.hl7.fhir.dstu2016may.model.Patient();
+ patient.addIdentifier().setUse(org.hl7.fhir.dstu2016may.model.Identifier.IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
+
+ org.hl7.fhir.dstu2016may.model.Extension ext = new org.hl7.fhir.dstu2016may.model.Extension();
+ ext.setUrl("http://example.com/extensions#someext");
+ ext.setValue(new org.hl7.fhir.dstu2016may.model.DateTimeType("2011-01-02T11:13:15"));
+ patient.addExtension(ext);
+
+ org.hl7.fhir.dstu2016may.model.Extension parent = new org.hl7.fhir.dstu2016may.model.Extension().setUrl("http://example.com#parent");
+ patient.addExtension(parent);
+ org.hl7.fhir.dstu2016may.model.Extension child1 = new org.hl7.fhir.dstu2016may.model.Extension().setUrl("http://example.com#child").setValue(new org.hl7.fhir.dstu2016may.model.StringType("value1"));
+ parent.addExtension(child1);
+ org.hl7.fhir.dstu2016may.model.Extension child2 = new org.hl7.fhir.dstu2016may.model.Extension().setUrl("http://example.com#child").setValue(new org.hl7.fhir.dstu2016may.model.StringType("value2"));
+ parent.addExtension(child2);
+
+ org.hl7.fhir.dstu2016may.model.Extension modExt = new org.hl7.fhir.dstu2016may.model.Extension();
+ modExt.setUrl("http://example.com/extensions#modext");
+ modExt.setValue(new org.hl7.fhir.dstu2016may.model.DateType("1995-01-02"));
+ patient.addModifierExtension(modExt);
+
+ org.hl7.fhir.dstu2016may.model.HumanName name = patient.addName();
+ name.addFamily("Blah");
+ org.hl7.fhir.dstu2016may.model.StringType given = name.addGivenElement();
+ given.setValue("Joe");
+ org.hl7.fhir.dstu2016may.model.Extension ext2 = new org.hl7.fhir.dstu2016may.model.Extension().setUrl("http://examples.com#givenext").setValue(new org.hl7.fhir.dstu2016may.model.StringType("given"));
+ given.addExtension(ext2);
+
+ org.hl7.fhir.dstu2016may.model.StringType given2 = name.addGivenElement();
+ given2.setValue("Shmoe");
+ org.hl7.fhir.dstu2016may.model.Extension given2ext = new org.hl7.fhir.dstu2016may.model.Extension().setUrl("http://examples.com#givenext_parent");
+ given2.addExtension(given2ext);
+ given2ext.addExtension(new org.hl7.fhir.dstu2016may.model.Extension().setUrl("http://examples.com#givenext_child").setValue(new org.hl7.fhir.dstu2016may.model.StringType("CHILD")));
+
+ String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(output);
+
+ String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
+ assertThat(enc, stringContainsInOrder("{\"resourceType\":\"Patient\",", "\"extension\":[{\"url\":\"http://example.com/extensions#someext\",\"valueDateTime\":\"2011-01-02T11:13:15\"}",
+ "{\"url\":\"http://example.com#parent\",\"extension\":[{\"url\":\"http://example.com#child\",\"valueString\":\"value1\"},{\"url\":\"http://example.com#child\",\"valueString\":\"value2\"}]}"));
+ assertThat(enc, stringContainsInOrder("\"modifierExtension\":[" + "{" + "\"url\":\"http://example.com/extensions#modext\"," + "\"valueDate\":\"1995-01-02\"" + "}" + "],"));
+ assertThat(enc,
+ containsString("\"_given\":[" + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext\"," + "\"valueString\":\"given\"" + "}" + "]" + "}," + "{" + "\"extension\":[" + "{"
+ + "\"url\":\"http://examples.com#givenext_parent\"," + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext_child\"," + "\"valueString\":\"CHILD\"" + "}" + "]" + "}"
+ + "]" + "}"));
+
+ /*
+ * Now parse this back
+ */
+
+ org.hl7.fhir.dstu2016may.model.Patient parsed = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Patient.class, enc);
+ ext = parsed.getExtension().get(0);
+ assertEquals("http://example.com/extensions#someext", ext.getUrl());
+ assertEquals("2011-01-02T11:13:15", ((org.hl7.fhir.dstu2016may.model.DateTimeType) ext.getValue()).getValueAsString());
+
+ parent = patient.getExtension().get(1);
+ assertEquals("http://example.com#parent", parent.getUrl());
+ assertNull(parent.getValue());
+ child1 = parent.getExtension().get(0);
+ assertEquals("http://example.com#child", child1.getUrl());
+ assertEquals("value1", ((org.hl7.fhir.dstu2016may.model.StringType) child1.getValue()).getValueAsString());
+ child2 = parent.getExtension().get(1);
+ assertEquals("http://example.com#child", child2.getUrl());
+ assertEquals("value2", ((org.hl7.fhir.dstu2016may.model.StringType) child2.getValue()).getValueAsString());
+
+ modExt = parsed.getModifierExtension().get(0);
+ assertEquals("http://example.com/extensions#modext", modExt.getUrl());
+ assertEquals("1995-01-02", ((org.hl7.fhir.dstu2016may.model.DateType) modExt.getValue()).getValueAsString());
+
+ name = parsed.getName().get(0);
+
+ ext2 = name.getGiven().get(0).getExtension().get(0);
+ assertEquals("http://examples.com#givenext", ext2.getUrl());
+ assertEquals("given", ((org.hl7.fhir.dstu2016may.model.StringType) ext2.getValue()).getValueAsString());
+
+ given2ext = name.getGiven().get(1).getExtension().get(0);
+ assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
+ assertNull(given2ext.getValue());
+ org.hl7.fhir.dstu2016may.model.Extension given2ext2 = given2ext.getExtension().get(0);
+ assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
+ assertEquals("CHILD", ((org.hl7.fhir.dstu2016may.model.StringType) given2ext2.getValue()).getValue());
+
+ }
+
+ @Test
+ public void testEncodeAndParseMetaProfileAndTags() {
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.addName().addFamily("FAMILY");
+
+ p.getMeta().addProfile("http://foo/Profile1");
+ p.getMeta().addProfile("http://foo/Profile2");
+
+ p.getMeta().addTag().setSystem("scheme1").setCode("term1").setDisplay("label1");
+ p.getMeta().addTag().setSystem("scheme2").setCode("term2").setDisplay("label2");
+
+ p.getMeta().addSecurity().setSystem("sec_scheme1").setCode("sec_term1").setDisplay("sec_label1");
+ p.getMeta().addSecurity().setSystem("sec_scheme2").setCode("sec_term2").setDisplay("sec_label2");
+
+ String enc = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+
+ //@formatter:off
+ assertThat(enc, stringContainsInOrder("\"meta\": {",
+ "\"profile\": [",
+ "\"http://foo/Profile1\",",
+ "\"http://foo/Profile2\"",
+ "],",
+ "\"security\": [",
+ "{",
+ "\"system\": \"sec_scheme1\",",
+ "\"code\": \"sec_term1\",",
+ "\"display\": \"sec_label1\"",
+ "},",
+ "{",
+ "\"system\": \"sec_scheme2\",",
+ "\"code\": \"sec_term2\",",
+ "\"display\": \"sec_label2\"",
+ "}",
+ "],",
+ "\"tag\": [",
+ "{",
+ "\"system\": \"scheme1\",",
+ "\"code\": \"term1\",",
+ "\"display\": \"label1\"",
+ "},",
+ "{",
+ "\"system\": \"scheme2\",",
+ "\"code\": \"term2\",",
+ "\"display\": \"label2\"",
+ "}",
+ "]",
+ "},"));
+ //@formatter:on
+
+ org.hl7.fhir.dstu2016may.model.Patient parsed = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Patient.class, enc);
+
+ List gotLabels = parsed.getMeta().getProfile();
+ assertEquals(2, gotLabels.size());
+ org.hl7.fhir.dstu2016may.model.UriType label = gotLabels.get(0);
+ assertEquals("http://foo/Profile1", label.getValue());
+ label = gotLabels.get(1);
+ assertEquals("http://foo/Profile2", label.getValue());
+
+ List tagList = parsed.getMeta().getTag();
+ assertEquals(2, tagList.size());
+ assertEquals("scheme1", tagList.get(0).getSystem());
+ assertEquals("term1", tagList.get(0).getCode());
+ assertEquals("label1", tagList.get(0).getDisplay());
+ assertEquals("scheme2", tagList.get(1).getSystem());
+ assertEquals("term2", tagList.get(1).getCode());
+ assertEquals("label2", tagList.get(1).getDisplay());
+
+ tagList = parsed.getMeta().getSecurity();
+ assertEquals(2, tagList.size());
+ assertEquals("sec_scheme1", tagList.get(0).getSystem());
+ assertEquals("sec_term1", tagList.get(0).getCode());
+ assertEquals("sec_label1", tagList.get(0).getDisplay());
+ assertEquals("sec_scheme2", tagList.get(1).getSystem());
+ assertEquals("sec_term2", tagList.get(1).getCode());
+ assertEquals("sec_label2", tagList.get(1).getDisplay());
+ }
+
+ /**
+ * See #336
+ */
+ @Test
+ public void testEncodeAndParseNullPrimitiveWithExtensions() {
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setId("patid");
+ org.hl7.fhir.dstu2016may.model.HumanName name = p.addName();
+ name.addGivenElement().setValue(null).setId("f0").addExtension(new org.hl7.fhir.dstu2016may.model.Extension("http://foo", new org.hl7.fhir.dstu2016may.model.StringType("FOOEXT0")));
+ name.addGivenElement().setValue("V1").setId("f1").addExtension((org.hl7.fhir.dstu2016may.model.Extension) new org.hl7.fhir.dstu2016may.model.Extension("http://foo", new org.hl7.fhir.dstu2016may.model.StringType("FOOEXT1")).setId("ext1id"));
+ name.addGivenElement(); // this one shouldn't get encoded
+ name.addGivenElement().setValue(null).addExtension(new org.hl7.fhir.dstu2016may.model.Extension("http://foo", new org.hl7.fhir.dstu2016may.model.StringType("FOOEXT3")));
+ name.setId("nameid");
+
+ String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(output);
+
+ output = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(p);
+ String expected = "{\"resourceType\":\"Patient\",\"id\":\"patid\",\"name\":[{\"id\":\"nameid\",\"given\":[null,\"V1\",null],\"_given\":[{\"id\":\"f0\",\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"FOOEXT0\"}]},{\"id\":\"f1\",\"extension\":[{\"id\":\"ext1id\",\"url\":\"http://foo\",\"valueString\":\"FOOEXT1\"}]},{\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"FOOEXT3\"}]}]}]}";
+
+ ourLog.info("Exp: {}", expected);
+ ourLog.info("Act: {}", output);
+
+ assertEquals(expected, output);
+
+ p = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Patient.class, output);
+ assertEquals("patid", p.getIdElement().getIdPart());
+
+ name = p.getName().get(0);
+ assertEquals("nameid", name.getId());
+ assertEquals(3, name.getGiven().size());
+
+ assertEquals(null, name.getGiven().get(0).getValue());
+ assertEquals("V1", name.getGiven().get(1).getValue());
+ assertEquals(null, name.getGiven().get(2).getValue());
+
+ assertEquals("f0", name.getGiven().get(0).getId());
+ assertEquals("f1", name.getGiven().get(1).getId());
+ assertEquals(null, name.getGiven().get(2).getId());
+
+ assertEquals(1, name.getGiven().get(0).getExtension().size());
+ assertEquals("http://foo", name.getGiven().get(0).getExtension().get(0).getUrl());
+ assertEquals("FOOEXT0", ((org.hl7.fhir.dstu2016may.model.StringType) name.getGiven().get(0).getExtension().get(0).getValue()).getValue());
+ assertEquals(null, name.getGiven().get(0).getExtension().get(0).getId());
+
+ assertEquals(1, name.getGiven().get(1).getExtension().size());
+ assertEquals("http://foo", name.getGiven().get(1).getExtension().get(0).getUrl());
+ assertEquals("FOOEXT1", ((org.hl7.fhir.dstu2016may.model.StringType) name.getGiven().get(1).getExtension().get(0).getValue()).getValue());
+ assertEquals("ext1id", name.getGiven().get(1).getExtension().get(0).getId());
+
+ assertEquals(1, name.getGiven().get(2).getExtension().size());
+ assertEquals("http://foo", name.getGiven().get(2).getExtension().get(0).getUrl());
+ assertEquals("FOOEXT3", ((org.hl7.fhir.dstu2016may.model.StringType) name.getGiven().get(2).getExtension().get(0).getValue()).getValue());
+ assertEquals(null, name.getGiven().get(2).getExtension().get(0).getId());
+
+ }
+
+
+
+ @Test
+ public void testEncodeBundleNewBundleNoText() {
+
+ org.hl7.fhir.dstu2016may.model.Bundle b = new org.hl7.fhir.dstu2016may.model.Bundle();
+
+ org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent e = b.addEntry();
+ e.setResource(new org.hl7.fhir.dstu2016may.model.Patient());
+
+ String val = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(b);
+ ourLog.info(val);
+ assertThat(val, not(containsString("text")));
+
+ val = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(b);
+ ourLog.info(val);
+ assertThat(val, not(containsString("text")));
+
+ }
+
+ /**
+ * See #326
+ */
+ @Test
+ public void testEncodeContainedResource() {
+ org.hl7.fhir.dstu2016may.model.Patient patient = new org.hl7.fhir.dstu2016may.model.Patient();
+ patient.getBirthDateElement().setValueAsString("2016-04-05");
+ patient.addExtension().setUrl("test").setValue(new org.hl7.fhir.dstu2016may.model.Reference(new org.hl7.fhir.dstu2016may.model.Condition()));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "{",
+ "\"resourceType\": \"Patient\",",
+ "\"contained\": [",
+ "{",
+ "\"resourceType\": \"Condition\",",
+ "\"id\": \"1\"",
+ "}",
+ "],",
+ "\"extension\": [",
+ "{",
+ "\"url\": \"test\",",
+ "\"valueReference\": {",
+ "\"reference\": \"#1\"",
+ "}",
+ "}",
+ "],",
+ "\"birthDate\": \"2016-04-05\"",
+ "}"
+ ));
+ //@formatter:on
+ }
+
+ @Test
+ public void testEncodeDoesntIncludeUuidId() {
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setId(new org.hl7.fhir.dstu2016may.model.IdType("urn:uuid:42795ed8-041f-4ebf-b6f4-78ef6f64c2f2"));
+ p.addIdentifier().setSystem("ACME");
+
+ String actual = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
+ assertThat(actual, not(containsString("78ef6f64c2f2")));
+ }
+
+ @Test
+ public void testEncodeEmptyBinary() {
+ String output = ourCtx.newJsonParser().encodeResourceToString(new org.hl7.fhir.dstu2016may.model.Binary());
+ assertEquals("{\"resourceType\":\"Binary\"}", output);
+ }
+
+ /**
+ * #158
+ */
+ @Test
+ public void testEncodeEmptyTag() {
+ ArrayList tagList = new ArrayList();
+ tagList.add(new org.hl7.fhir.dstu2016may.model.Coding());
+ tagList.add(new org.hl7.fhir.dstu2016may.model.Coding().setDisplay("Label"));
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.getMeta().getTag().addAll(tagList);
+
+ String encoded = ourCtx.newJsonParser().encodeResourceToString(p);
+ assertThat(encoded, not(containsString("tag")));
+ }
+
+ /**
+ * #158
+ */
+ @Test
+ public void testEncodeEmptyTag2() {
+ ArrayList tagList = new ArrayList();
+ tagList.add(new org.hl7.fhir.dstu2016may.model.Coding().setSystem("scheme").setCode("code"));
+ tagList.add(new org.hl7.fhir.dstu2016may.model.Coding().setDisplay("Label"));
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.getMeta().getTag().addAll(tagList);
+
+ String encoded = ourCtx.newJsonParser().encodeResourceToString(p);
+ assertThat(encoded, containsString("tag"));
+ assertThat(encoded, containsString("scheme"));
+ assertThat(encoded, not(containsString("Label")));
+ }
+
+ @Test
+ public void testEncodeExtendedInfrastructureComponent() {
+ IParser parser = ourCtx.newJsonParser();
+
+ PatientWithExtendedContactDstu3 patient = new PatientWithExtendedContactDstu3();
+ patient.setId("123");
+
+ PatientWithExtendedContactDstu3.CustomContactComponent customContactComponent = new PatientWithExtendedContactDstu3.CustomContactComponent();
+ customContactComponent.getEyeColour().setValue("EYE");
+ customContactComponent.getName().addFamily("FAMILY");
+ patient.getCustomContact().add(customContactComponent);
+
+ String val = parser.encodeResourceToString(patient);
+ ourLog.info(val);
+
+ assertEquals(
+ "{\"resourceType\":\"Patient\",\"id\":\"123\",\"contact\":[{\"extension\":[{\"url\":\"http://foo.com/contact-eyecolour\",\"valueIdentifier\":{\"value\":\"EYE\"}}],\"name\":{\"family\":[\"FAMILY\"]}}]}",
+ val);
+
+ FhirContext newCtx = FhirContext.forDstu2_1();
+ PatientWithExtendedContactDstu3 actual = newCtx.newJsonParser().parseResource(PatientWithExtendedContactDstu3.class, val);
+ assertEquals("EYE", actual.getCustomContact().get(0).getEyeColour().getValue());
+
+ }
+
+ @Test
+ public void testEncodeExtensionInPrimitiveElement() {
+
+ Conformance c = new Conformance();
+ c.getAcceptUnknownElement().addExtension().setUrl("http://foo").setValue(new org.hl7.fhir.dstu2016may.model.StringType("AAA"));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(c);
+ ourLog.info(encoded);
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(c);
+ ourLog.info(encoded);
+ assertEquals(encoded, "{\"resourceType\":\"Conformance\",\"_acceptUnknown\":{\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"AAA\"}]}}");
+
+ // Now with a value
+ ourLog.info("---------------");
+
+ c = new Conformance();
+ c.getAcceptUnknownElement().setValue(Conformance.UnknownContentCode.ELEMENTS);
+ c.getAcceptUnknownElement().addExtension().setUrl("http://foo").setValue(new org.hl7.fhir.dstu2016may.model.StringType("AAA"));
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(c);
+ ourLog.info(encoded);
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(c);
+ ourLog.info(encoded);
+ assertEquals(encoded, "{\"resourceType\":\"Conformance\",\"acceptUnknown\":\"elements\",\"_acceptUnknown\":{\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"AAA\"}]}}");
+
+ }
+
+ @Test
+ public void testEncodeExtensionUndeclaredNonModifier() {
+ org.hl7.fhir.dstu2016may.model.Observation obs = new org.hl7.fhir.dstu2016may.model.Observation();
+ obs.setId("1");
+ obs.getMeta().addProfile("http://profile");
+ org.hl7.fhir.dstu2016may.model.Extension ext = obs.addExtension();
+ ext.setUrl("http://exturl").setValue(new org.hl7.fhir.dstu2016may.model.StringType("ext_url_value"));
+
+ obs.getCode().setText("CODE");
+
+ IParser parser = ourCtx.newJsonParser();
+
+ String output = parser.setPrettyPrint(true).encodeResourceToString(obs);
+ ourLog.info(output);
+
+ //@formatter:off
+ assertThat(output, stringContainsInOrder(
+ "\"id\": \"1\"",
+ "\"meta\"",
+ "\"extension\"",
+ "\"url\": \"http://exturl\"",
+ "\"valueString\": \"ext_url_value\"",
+ "\"code\":"
+ ));
+ assertThat(output, not(stringContainsInOrder(
+ "\"url\": \"http://exturl\"",
+ ",",
+ "\"url\": \"http://exturl\""
+ )));
+ //@formatter:on
+
+ obs = parser.parseResource(org.hl7.fhir.dstu2016may.model.Observation.class, output);
+ assertEquals(1, obs.getExtension().size());
+ assertEquals("http://exturl", obs.getExtension().get(0).getUrl());
+ assertEquals("ext_url_value", ((org.hl7.fhir.dstu2016may.model.StringType) obs.getExtension().get(0).getValue()).getValue());
+ }
+
+ @Test
+ public void testEncodeExtensionUndeclaredNonModifierWithChildExtension() {
+ org.hl7.fhir.dstu2016may.model.Observation obs = new org.hl7.fhir.dstu2016may.model.Observation();
+ obs.setId("1");
+ obs.getMeta().addProfile("http://profile");
+ org.hl7.fhir.dstu2016may.model.Extension ext = obs.addExtension();
+ ext.setUrl("http://exturl");
+
+ org.hl7.fhir.dstu2016may.model.Extension subExt = ext.addExtension();
+ subExt.setUrl("http://subext").setValue(new org.hl7.fhir.dstu2016may.model.StringType("sub_ext_value"));
+
+ obs.getCode().setText("CODE");
+
+ IParser parser = ourCtx.newJsonParser();
+
+ String output = parser.setPrettyPrint(true).encodeResourceToString(obs);
+ ourLog.info(output);
+
+ //@formatter:off
+ assertThat(output, stringContainsInOrder(
+ "\"id\": \"1\"",
+ "\"meta\"",
+ "\"extension\"",
+ "\"url\": \"http://exturl\"",
+ "\"extension\"",
+ "\"url\": \"http://subext\"",
+ "\"valueString\": \"sub_ext_value\"",
+ "\"code\":"
+ ));
+ assertThat(output, not(stringContainsInOrder(
+ "\"url\": \"http://exturl\"",
+ ",",
+ "\"url\": \"http://exturl\""
+ )));
+ //@formatter:on
+
+ obs = parser.parseResource(org.hl7.fhir.dstu2016may.model.Observation.class, output);
+ assertEquals(1, obs.getExtension().size());
+ assertEquals("http://exturl", obs.getExtension().get(0).getUrl());
+ assertEquals(1, obs.getExtension().get(0).getExtension().size());
+ assertEquals("http://subext", obs.getExtension().get(0).getExtension().get(0).getUrl());
+ assertEquals("sub_ext_value", ((org.hl7.fhir.dstu2016may.model.StringType) obs.getExtension().get(0).getExtension().get(0).getValue()).getValue());
+ }
+
+ @Test
+ public void testEncodeHistoryEncodeVersionsAtPath1() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setManagingOrganization(new org.hl7.fhir.dstu2016may.model.Reference("http://foo.com/Organization/2/_history/1"));
+
+ IParser parser = ourCtx.newJsonParser();
+
+ parser.setDontStripVersionsFromReferencesAtPaths("Patient.managingOrganization");
+ String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
+ }
+
+ @Test
+ public void testEncodeHistoryEncodeVersionsAtPath2() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
+ assertTrue(ourCtx.getParserOptions().isStripVersionsFromReferences());
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setManagingOrganization(new org.hl7.fhir.dstu2016may.model.Reference("http://foo.com/Organization/2/_history/1"));
+
+ IParser parser = ourCtx.newJsonParser();
+
+ parser.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference");
+ String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
+ }
+
+ @Test
+ public void testEncodeHistoryEncodeVersionsAtPath3() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
+
+ org.hl7.fhir.dstu2016may.model.AuditEvent auditEvent = new org.hl7.fhir.dstu2016may.model.AuditEvent();
+ auditEvent.addEntity().setReference(new org.hl7.fhir.dstu2016may.model.Reference("http://foo.com/Organization/2/_history/1"));
+
+ IParser parser = ourCtx.newJsonParser();
+
+ parser.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference");
+ String enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
+
+ parser.setDontStripVersionsFromReferencesAtPaths(new ArrayList());
+ enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
+
+ parser.setDontStripVersionsFromReferencesAtPaths((String[]) null);
+ enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
+
+ parser.setDontStripVersionsFromReferencesAtPaths((List) null);
+ enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
+ }
+
+ @Test
+ public void testEncodeHistoryEncodeVersionsAtPathUsingOptions() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
+ assertTrue(ourCtx.getParserOptions().isStripVersionsFromReferences());
+ assertThat(ourCtx.getParserOptions().getDontStripVersionsFromReferencesAtPaths(), empty());
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setManagingOrganization(new org.hl7.fhir.dstu2016may.model.Reference("http://foo.com/Organization/2/_history/1"));
+
+ IParser parser = ourCtx.newJsonParser();
+
+ ourCtx.getParserOptions().setDontStripVersionsFromReferencesAtPaths("Patient.managingOrganization");
+ String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
+
+ ourCtx.getParserOptions().setDontStripVersionsFromReferencesAtPaths(Arrays.asList("Patient.managingOrganization"));
+ enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
+
+ ourCtx.getParserOptions().setDontStripVersionsFromReferencesAtPaths(new HashSet(Arrays.asList("Patient.managingOrganization")));
+ enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
+ }
+
+ @Test
+ public void testEncodeHistoryStripVersionsFromReferences() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ assertNull(ourCtx.newJsonParser().getStripVersionsFromReferences());
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setManagingOrganization(new org.hl7.fhir.dstu2016may.model.Reference("http://foo.com/Organization/2/_history/1"));
+
+ IParser parser = ourCtx.newJsonParser();
+ String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
+
+ parser.setStripVersionsFromReferences(false);
+ enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
+
+ ourCtx = FhirContext.forDstu2_1();
+ }
+
+ @Test
+ public void testEncodeHistoryStripVersionsFromReferencesFromContext() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ assertTrue(ourCtx.getParserOptions().isStripVersionsFromReferences());
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setManagingOrganization(new org.hl7.fhir.dstu2016may.model.Reference("http://foo.com/Organization/2/_history/1"));
+
+ IParser parser = ourCtx.newJsonParser();
+ String enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
+
+ ourCtx.getParserOptions().setStripVersionsFromReferences(false);
+ enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2/_history/1\""));
+
+ parser.setStripVersionsFromReferences(true);
+ enc = parser.setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+ assertThat(enc, containsString("\"reference\": \"http://foo.com/Organization/2\""));
+
+ ourCtx = FhirContext.forDstu2_1();
+ }
+
+ @Test
+ public void testEncodeNarrativeShouldIncludeNamespace() {
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.getText().setDivAsString("VALUE
");
+
+ String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(output);
+ assertThat(output, containsString("\"div\": \"VALUE
\""));
+ }
+
+ @Test
+ public void testEncodeNarrativeShouldIncludeNamespaceWithProcessingInstruction() {
+
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.getText().setDivAsString("VALUE
");
+
+ String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(output);
+ assertThat(output, containsString("\"div\": \"VALUE
\""));
+ }
+
+ @Test
+ public void testEncodeNarrativeSuppressed() throws Exception {
+ org.hl7.fhir.dstu2016may.model.Patient patient = new org.hl7.fhir.dstu2016may.model.Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.getMaritalStatus().addCoding().setCode("D");
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).setSuppressNarratives(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("Patient"));
+ assertThat(encoded, stringContainsInOrder(ca.uhn.fhir.rest.api.Constants.TAG_SUBSETTED_SYSTEM, ca.uhn.fhir.rest.api.Constants.TAG_SUBSETTED_CODE));
+ assertThat(encoded, not(containsString("text")));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, containsString("maritalStatus"));
+ }
+
+ @Test
+ public void testEncodeParametersWithId() {
+ org.hl7.fhir.dstu2016may.model.Parameters reqParms = new org.hl7.fhir.dstu2016may.model.Parameters();
+ org.hl7.fhir.dstu2016may.model.IdType patient = new org.hl7.fhir.dstu2016may.model.IdType(1);
+ reqParms.addParameter().setName("patient").setValue(patient);
+
+ String enc = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(reqParms);
+ ourLog.info(enc);
+
+ assertThat(enc, containsString("\"valueId\": \"1\""));
+ }
+
+ @Test
+ public void testEncodeSummary() {
+ org.hl7.fhir.dstu2016may.model.Patient patient = new org.hl7.fhir.dstu2016may.model.Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.addPhoto().setTitle("green");
+ patient.getMaritalStatus().addCoding().setCode("D");
+
+ ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).setSummaryMode(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("Patient"));
+ assertThat(encoded, stringContainsInOrder("\"tag\"", "\"system\": \"" + ca.uhn.fhir.rest.api.Constants.TAG_SUBSETTED_SYSTEM + "\",", "\"code\": \"" + ca.uhn.fhir.rest.api.Constants.TAG_SUBSETTED_CODE + "\""));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, not(containsString("maritalStatus")));
+ }
+
+ @Test
+ public void testEncodeSummary2() {
+ org.hl7.fhir.dstu2016may.model.Patient patient = new org.hl7.fhir.dstu2016may.model.Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.getMaritalStatus().addCoding().setCode("D");
+
+ patient.getMeta().addTag().setSystem("foo").setCode("bar");
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).setSummaryMode(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("Patient"));
+ assertThat(encoded, stringContainsInOrder("\"tag\"", "\"system\": \"foo\",", "\"code\": \"bar\"", "\"system\": \"" + ca.uhn.fhir.rest.api.Constants.TAG_SUBSETTED_SYSTEM + "\"",
+ "\"code\": \"" + ca.uhn.fhir.rest.api.Constants.TAG_SUBSETTED_CODE + "\""));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, not(containsString("maritalStatus")));
+ }
+
+ /**
+ * See #205
+ */
+ @Test
+ public void testEncodeTags() {
+ org.hl7.fhir.dstu2016may.model.Patient pt = new org.hl7.fhir.dstu2016may.model.Patient();
+ pt.addIdentifier().setSystem("sys").setValue("val");
+
+ pt.getMeta().addTag().setSystem("scheme").setCode("term").setDisplay("display");
+
+ String enc = ourCtx.newJsonParser().encodeResourceToString(pt);
+ ourLog.info(enc);
+
+ assertEquals("{\"resourceType\":\"Patient\",\"meta\":{\"tag\":[{\"system\":\"scheme\",\"code\":\"term\",\"display\":\"display\"}]},\"identifier\":[{\"system\":\"sys\",\"value\":\"val\"}]}",
+ enc);
+
+ }
+
+ /**
+ * See #241
+ */
+ @Test
+ public void testEncodeThenParseShouldNotAddSpuriousId() throws Exception {
+ org.hl7.fhir.dstu2016may.model.Condition condition = new org.hl7.fhir.dstu2016may.model.Condition().setVerificationStatus(org.hl7.fhir.dstu2016may.model.Condition.ConditionVerificationStatus.CONFIRMED);
+ org.hl7.fhir.dstu2016may.model.Bundle bundle = new org.hl7.fhir.dstu2016may.model.Bundle();
+ org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent entry = new org.hl7.fhir.dstu2016may.model.Bundle.BundleEntryComponent();
+ entry.setId("123");
+ entry.setResource(condition);
+ bundle.getEntry().add(entry);
+ IParser parser = ourCtx.newJsonParser();
+ String json = parser.encodeResourceToString(bundle);
+ ourLog.info(json);
+ bundle = (org.hl7.fhir.dstu2016may.model.Bundle) parser.parseResource(json);
+
+ assertEquals("123", bundle.getEntry().get(0).getId());
+
+ condition = (org.hl7.fhir.dstu2016may.model.Condition) bundle.getEntry().get(0).getResource();
+ assertEquals(null, condition.getId());
+ }
+
+ @Test
+ public void testEncodeWithDontEncodeElements() throws Exception {
+ org.hl7.fhir.dstu2016may.model.Patient patient = new org.hl7.fhir.dstu2016may.model.Patient();
+ patient.setId("123");
+
+ patient.getMeta().addProfile(("http://profile"));
+ patient.addName().addFamily("FAMILY").addGiven("GIVEN");
+ patient.addAddress().addLine("LINE1");
+
+ {
+ IParser p = ourCtx.newJsonParser();
+ p.setDontEncodeElements(Sets.newHashSet("*.meta", "*.id"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("address"));
+ assertThat(out, not(containsString("id")));
+ assertThat(out, not(containsString("meta")));
+ }
+ {
+ IParser p = ourCtx.newJsonParser();
+ p.setDontEncodeElements(Sets.newHashSet("Patient.meta", "Patient.id"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("address"));
+ assertThat(out, not(containsString("id")));
+ assertThat(out, not(containsString("meta")));
+ }
+ {
+ IParser p = ourCtx.newJsonParser();
+ p.setDontEncodeElements(Sets.newHashSet("Patient.name.family"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("GIVEN"));
+ assertThat(out, not(containsString("FAMILY")));
+ }
+ {
+ IParser p = ourCtx.newJsonParser();
+ p.setDontEncodeElements(Sets.newHashSet("*.meta", "*.id"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("address"));
+ assertThat(out, not(containsString("id")));
+ assertThat(out, not(containsString("meta")));
+ }
+ {
+ IParser p = ourCtx.newJsonParser();
+ p.setDontEncodeElements(Sets.newHashSet("Patient.meta"));
+ p.setEncodeElements(new HashSet(Arrays.asList("Patient.name")));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("id"));
+ assertThat(out, not(containsString("address")));
+ assertThat(out, not(containsString("meta")));
+ }
+ }
+
+ @Test
+ public void testEncodingNullExtension() {
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ org.hl7.fhir.dstu2016may.model.Extension extension = new org.hl7.fhir.dstu2016may.model.Extension("http://foo#bar");
+ p.addExtension(extension);
+ String str = ourCtx.newJsonParser().encodeResourceToString(p);
+
+ assertEquals("{\"resourceType\":\"Patient\"}", str);
+
+ extension.setValue(new org.hl7.fhir.dstu2016may.model.StringType());
+
+ str = ourCtx.newJsonParser().encodeResourceToString(p);
+ assertEquals("{\"resourceType\":\"Patient\"}", str);
+
+ extension.setValue(new org.hl7.fhir.dstu2016may.model.StringType(""));
+
+ str = ourCtx.newJsonParser().encodeResourceToString(p);
+ assertEquals("{\"resourceType\":\"Patient\"}", str);
+
+ }
+
+
+ @Test
+ public void testExponentDoesntGetEncodedAsSuch() {
+ org.hl7.fhir.dstu2016may.model.Observation obs = new org.hl7.fhir.dstu2016may.model.Observation();
+ obs.setValue(new org.hl7.fhir.dstu2016may.model.Quantity().setValue(new BigDecimal("0.000000000000000100")));
+
+ String str = ourCtx.newJsonParser().encodeResourceToString(obs);
+ ourLog.info(str);
+
+ assertEquals("{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.000000000000000100}}", str);
+ }
+
+ @Test
+ public void testExponentParseWorks() {
+ String input = "{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.0000000000000001}}";
+ org.hl7.fhir.dstu2016may.model.Observation obs = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Observation.class, input);
+
+ assertEquals("0.0000000000000001", ((org.hl7.fhir.dstu2016may.model.Quantity) obs.getValue()).getValueElement().getValueAsString());
+
+ String str = ourCtx.newJsonParser().encodeResourceToString(obs);
+ ourLog.info(str);
+ assertEquals("{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.0000000000000001}}", str);
+ }
+
+ /**
+ * #516
+ */
+ @Test(expected = DataFormatException.class)
+ public void testInvalidEnumValue() {
+ String res = "{ \"resourceType\": \"ValueSet\", \"url\": \"http://sample/ValueSet/education-levels\", \"version\": \"1\", \"name\": \"Education Levels\", \"status\": \"draft\", \"compose\": { \"include\": [ { \"filter\": [ { \"property\": \"n\", \"op\": \"n\", \"value\": \"365460000\" } ], \"system\": \"http://snomed.info/sct\" } ], \"exclude\": [ { \"concept\": [ { \"code\": \"224298008\" }, { \"code\": \"365460000\" }, { \"code\": \"473462005\" }, { \"code\": \"424587006\" } ], \"system\": \"http://snomed.info/sct\" } ] }, \"description\": \"A selection of Education Levels\", \"text\": { \"status\": \"generated\", \"div\": \"Education Levels http://csiro.au/ValueSet/education-levels A selection of Education Levels
\" }, \"experimental\": true, \"date\": \"2016-07-26\" }";
+ IParser parser = ourCtx.newJsonParser();
+ parser.setParserErrorHandler(new StrictErrorHandler());
+ org.hl7.fhir.dstu2016may.model.ValueSet parsed = parser.parseResource(org.hl7.fhir.dstu2016may.model.ValueSet.class, res);
+ fail("DataFormat Invalid attribute exception should be thrown");
+ }
+
+ /**
+ * #65
+ */
+ @Test
+ public void testJsonPrimitiveWithExtensionEncoding() {
+
+ org.hl7.fhir.dstu2016may.model.QuestionnaireResponse parsed = new org.hl7.fhir.dstu2016may.model.QuestionnaireResponse();
+ parsed.addItem().setLinkId("value123");
+ parsed.getItem().get(0).getLinkIdElement().addExtension(new org.hl7.fhir.dstu2016may.model.Extension("http://123", new org.hl7.fhir.dstu2016may.model.StringType("HELLO")));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(parsed);
+ ourLog.info(encoded);
+ assertThat(encoded, containsString("{\"linkId\":\"value123\",\"_linkId\":{\"extension\":[{\"url\":\"http://123\",\"valueString\":\"HELLO\"}]}}"));
+
+ }
+
+ @Test
+ public void testLinkage() {
+ org.hl7.fhir.dstu2016may.model.Linkage l = new org.hl7.fhir.dstu2016may.model.Linkage();
+ l.addItem().getResource().setDisplay("FOO");
+ String out = ourCtx.newXmlParser().encodeResourceToString(l);
+ ourLog.info(out);
+ assertEquals(" ", out);
+ }
+
+ @Test
+ public void testOmitResourceId() {
+ org.hl7.fhir.dstu2016may.model.Patient p = new org.hl7.fhir.dstu2016may.model.Patient();
+ p.setId("123");
+ p.addName().addFamily("ABC");
+
+ assertThat(ourCtx.newJsonParser().encodeResourceToString(p), stringContainsInOrder("123", "ABC"));
+ assertThat(ourCtx.newJsonParser().setOmitResourceId(true).encodeResourceToString(p), containsString("ABC"));
+ assertThat(ourCtx.newJsonParser().setOmitResourceId(true).encodeResourceToString(p), not(containsString("123")));
+ }
+
+ @Test
+ public void testParseAndEncodeBundleWithUuidBase() {
+ //@formatter:off
+ String input =
+ "{\n" +
+ " \"resourceType\":\"Bundle\",\n" +
+ " \"type\":\"document\",\n" +
+ " \"entry\":[\n" +
+ " {\n" +
+ " \"fullUrl\":\"urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57\",\n" +
+ " \"resource\":{\n" +
+ " \"resourceType\":\"Composition\",\n" +
+ " \"id\":\"180f219f-97a8-486d-99d9-ed631fe4fc57\",\n" +
+ " \"meta\":{\n" +
+ " \"lastUpdated\":\"2013-05-28T22:12:21Z\"\n" +
+ " },\n" +
+ " \"text\":{\n" +
+ " \"status\":\"generated\",\n" +
+ " \"div\":\"\"\n" +
+ " },\n" +
+ " \"date\":\"2013-02-01T12:30:02Z\",\n" +
+ " \"type\":{\n" +
+ " \"coding\":[\n" +
+ " {\n" +
+ " \"system\":\"http://loinc.org\",\n" +
+ " \"code\":\"28655-9\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"text\":\"Discharge Summary from Responsible Clinician\"\n" +
+ " },\n" +
+ " \"status\":\"final\",\n" +
+ " \"confidentiality\":\"N\",\n" +
+ " \"subject\":{\n" +
+ " \"reference\":\"http://fhir.healthintersections.com.au/open/Patient/d1\",\n" +
+ " \"display\":\"Eve Everywoman\"\n" +
+ " },\n" +
+ " \"author\":[\n" +
+ " {\n" +
+ " \"reference\":\"Practitioner/example\",\n" +
+ " \"display\":\"Doctor Dave\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"encounter\":{\n" +
+ " \"reference\":\"http://fhir.healthintersections.com.au/open/Encounter/doc-example\"\n" +
+ " },\n" +
+ " \"section\":[\n" +
+ " {\n" +
+ " \"title\":\"Reason for admission\",\n" +
+ " \"content\":{\n" +
+ " \"reference\":\"urn:uuid:d0dd51d3-3ab2-4c84-b697-a630c3e40e7a\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"title\":\"Medications on Discharge\",\n" +
+ " \"content\":{\n" +
+ " \"reference\":\"urn:uuid:673f8db5-0ffd-4395-9657-6da00420bbc1\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"title\":\"Known allergies\",\n" +
+ " \"content\":{\n" +
+ " \"reference\":\"urn:uuid:68f86194-e6e1-4f65-b64a-5314256f8d7b\"\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " }" +
+ " ]" +
+ "}";
+ //@formatter:on
+
+ org.hl7.fhir.dstu2016may.model.Bundle parsed = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Bundle.class, input);
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
+ ourLog.info(encoded);
+
+ assertEquals("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57", parsed.getEntry().get(0).getResource().getIdElement().getValue());
+ assertEquals(null, parsed.getEntry().get(0).getResource().getIdElement().getBaseUrl());
+ assertEquals("urn:uuid:180f219f-97a8-486d-99d9-ed631fe4fc57", parsed.getEntry().get(0).getResource().getIdElement().getIdPart());
+ assertThat(encoded, not(containsString("\"id\":\"180f219f-97a8-486d-99d9-ed631fe4fc57\"")));
+ }
+
+ @Test
+ public void testParseAndEncodeComments() {
+ //@formatter:off
+ String input = "{\n" +
+ " \"resourceType\": \"Patient\",\n" +
+ " \"id\": \"pat1\",\n" +
+ " \"text\": {\n" +
+ " \"status\": \"generated\",\n" +
+ " \"div\": \"\\n \\n
Patient Donald DUCK @ Acme Healthcare, Inc. MR = 654321
\\n \\n
\"\n" +
+ " },\n" +
+ " \"identifier\": [\n" +
+ " {\n" +
+ " \"fhir_comments\":[\"identifier comment 1\",\"identifier comment 2\"],\n" +
+ " \"use\": \"usual\",\n" +
+ " \"_use\": {\n" +
+ " \"fhir_comments\":[\"use comment 1\",\"use comment 2\"]\n" +
+ " },\n" +
+ " \"type\": {\n" +
+ " \"coding\": [\n" +
+ " {\n" +
+ " \"system\": \"http://hl7.org/fhir/v2/0203\",\n" +
+ " \"code\": \"MR\"\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " \"system\": \"urn:oid:0.1.2.3.4.5.6.7\",\n" +
+ " \"value\": \"654321\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"active\": true" +
+ "}";
+ //@formatter:off
+
+ org.hl7.fhir.dstu2016may.model.Patient res = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Patient.class, input);
+ res.getFormatCommentsPre();
+ assertEquals("Patient/pat1", res.getId());
+ assertEquals("654321", res.getIdentifier().get(0).getValue());
+ assertEquals(true, res.getActive());
+
+ assertThat(res.getIdentifier().get(0).getFormatCommentsPre(), contains("identifier comment 1", "identifier comment 2"));
+ assertThat(res.getIdentifier().get(0).getUseElement().getFormatCommentsPre(), contains("use comment 1", "use comment 2"));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(res);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "\"identifier\": [",
+ "{",
+ "\"fhir_comments\":",
+ "[",
+ "\"identifier comment 1\"",
+ ",",
+ "\"identifier comment 2\"",
+ "]",
+ "\"use\": \"usual\",",
+ "\"_use\": {",
+ "\"fhir_comments\":",
+ "[",
+ "\"use comment 1\"",
+ ",",
+ "\"use comment 2\"",
+ "]",
+ "},",
+ "\"type\""
+ ));
+ //@formatter:off
+ }
+
+ @Test
+ public void testParseBundleWithBinary() {
+ org.hl7.fhir.dstu2016may.model.Binary patient = new org.hl7.fhir.dstu2016may.model.Binary();
+ patient.setId(new org.hl7.fhir.dstu2016may.model.IdType("http://base/Binary/11/_history/22"));
+ patient.setContentType("foo");
+ patient.setContent(new byte[] { 1, 2, 3, 4 });
+
+ String val = ourCtx.newJsonParser().encodeResourceToString(patient);
+
+ String expected = "{\"resourceType\":\"Binary\",\"id\":\"11\",\"meta\":{\"versionId\":\"22\"},\"contentType\":\"foo\",\"content\":\"AQIDBA==\"}";
+ ourLog.info("Expected: {}", expected);
+ ourLog.info("Actual : {}", val);
+ assertEquals(expected, val);
+ }
+
+
+
+
+ /**
+ * See #342
+ */
+ @Test()
+ public void testParseInvalid() {
+ try {
+ ourCtx.newJsonParser().parseResource("FOO");
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Failed to parse JSON content, error was: Content does not appear to be FHIR JSON, first non-whitespace character was: 'F' (must be '{')", e.getMessage());
+ }
+ try {
+ ourCtx.newJsonParser().parseResource("[\"aaa\"]");
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Failed to parse JSON content, error was: Content does not appear to be FHIR JSON, first non-whitespace character was: '[' (must be '{')", e.getMessage());
+ }
+
+ assertEquals(org.hl7.fhir.dstu2016may.model.Bundle.class, ourCtx.newJsonParser().parseResource(" {\"resourceType\" : \"Bundle\"}").getClass());
+
+ }
+
+ /**
+ * See #414
+ */
+ @Test
+ public void testParseJsonExtensionWithoutUrl() {
+ //@formatter:off
+ String input =
+ "{\"resourceType\":\"Patient\"," +
+ "\"extension\":[ {\"valueDateTime\":\"2011-01-02T11:13:15\"} ]" +
+ "}";
+ //@formatter:on
+
+ IParser parser = ourCtx.newJsonParser();
+ parser.setParserErrorHandler(new LenientErrorHandler());
+ org.hl7.fhir.dstu2016may.model.Patient parsed = (org.hl7.fhir.dstu2016may.model.Patient) parser.parseResource(input);
+ assertEquals(1, parsed.getExtension().size());
+ assertEquals(null, parsed.getExtension().get(0).getUrl());
+ assertEquals("2011-01-02T11:13:15", ((PrimitiveType>)parsed.getExtension().get(0).getValue()).getValueAsString());
+
+ try {
+ parser = ourCtx.newJsonParser();
+ parser.setParserErrorHandler(new StrictErrorHandler());
+ parser.parseResource(input);
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Resource is missing required element 'url' in parent element 'extension'", e.getMessage());
+ }
+
+ }
+
+ /**
+ * See #414
+ */
+ @Test
+ public void testParseJsonModifierExtensionWithoutUrl() {
+ //@formatter:off
+ String input =
+ "{\"resourceType\":\"Patient\"," +
+ "\"modifierExtension\":[ {\"valueDateTime\":\"2011-01-02T11:13:15\"} ]" +
+ "}";
+ //@formatter:on
+
+ IParser parser = ourCtx.newJsonParser();
+ parser.setParserErrorHandler(new LenientErrorHandler());
+ org.hl7.fhir.dstu2016may.model.Patient parsed = (org.hl7.fhir.dstu2016may.model.Patient) parser.parseResource(input);
+ assertEquals(1, parsed.getModifierExtension().size());
+ assertEquals(null, parsed.getModifierExtension().get(0).getUrl());
+ assertEquals("2011-01-02T11:13:15", ((PrimitiveType>)parsed.getModifierExtension().get(0).getValue()).getValueAsString());
+
+ try {
+ parser = ourCtx.newJsonParser();
+ parser.setParserErrorHandler(new StrictErrorHandler());
+ parser.parseResource(input);
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Resource is missing required element 'url' in parent element 'modifierExtension'", e.getMessage());
+ }
+
+ }
+
+ /**
+ * See #484
+ */
+ @Test
+ public void testParseNarrativeWithEmptyDiv() {
+ String input = "{\"resourceType\":\"Basic\",\"id\":\"1\",\"text\":{\"status\":\"generated\",\"div\":\"
\"}}";
+ org.hl7.fhir.dstu2016may.model.Basic basic = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Basic.class, input);
+ assertEquals(null, basic.getText().getDivAsString());
+
+ input = "{\"resourceType\":\"Basic\",\"id\":\"1\",\"text\":{\"status\":\"generated\",\"div\":\"
\"}}";
+ basic = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Basic.class, input);
+ assertEquals(null, basic.getText().getDivAsString());
+
+ input = "{\"resourceType\":\"Basic\",\"id\":\"1\",\"text\":{\"status\":\"generated\",\"div\":\"
\"}}";
+ basic = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Basic.class, input);
+ assertEquals("
", basic.getText().getDivAsString());
+
+ }
+
+ /**
+ * See #163
+ */
+ @Test
+ public void testParseResourceType() {
+ IParser jsonParser = ourCtx.newJsonParser().setPrettyPrint(true);
+
+ // Patient
+ org.hl7.fhir.dstu2016may.model.Patient patient = new org.hl7.fhir.dstu2016may.model.Patient();
+ String patientId = UUID.randomUUID().toString();
+ patient.setId(new org.hl7.fhir.dstu2016may.model.IdType("Patient", patientId));
+ patient.addName().addGiven("John").addFamily("Smith");
+ patient.setGender(org.hl7.fhir.dstu2016may.model.Enumerations.AdministrativeGender.MALE);
+ patient.setBirthDateElement(new org.hl7.fhir.dstu2016may.model.DateType("1987-04-16"));
+
+ // Bundle
+ org.hl7.fhir.dstu2016may.model.Bundle bundle = new org.hl7.fhir.dstu2016may.model.Bundle();
+ bundle.setType(org.hl7.fhir.dstu2016may.model.Bundle.BundleType.COLLECTION);
+ bundle.addEntry().setResource(patient);
+
+ String bundleText = jsonParser.encodeResourceToString(bundle);
+ ourLog.info(bundleText);
+
+ org.hl7.fhir.dstu2016may.model.Bundle reincarnatedBundle = jsonParser.parseResource(org.hl7.fhir.dstu2016may.model.Bundle.class, bundleText);
+ org.hl7.fhir.dstu2016may.model.Patient reincarnatedPatient = (org.hl7.fhir.dstu2016may.model.Patient) reincarnatedBundle.getEntry().get(0).getResource();
+
+ assertEquals("Patient", patient.getIdElement().getResourceType());
+ assertEquals("Patient", reincarnatedPatient.getIdElement().getResourceType());
+ }
+
+ /**
+ * See #207
+ */
+ @Test
+ public void testParseResourceWithInvalidType() {
+ String input = "{" + "\"resourceType\":\"Patient\"," + "\"contained\":[" + " {" + " \"rezType\":\"Organization\"" + " }" + " ]" + "}";
+
+ IParser jsonParser = ourCtx.newJsonParser().setPrettyPrint(true);
+ try {
+ jsonParser.parseResource(input);
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Missing required element 'resourceType' from JSON resource object, unable to parse", e.getMessage());
+ }
+ }
+
+ /**
+ * See #344
+ */
+ @Test
+ public void testParserIsCaseSensitive() {
+ org.hl7.fhir.dstu2016may.model.Observation obs = new org.hl7.fhir.dstu2016may.model.Observation();
+ org.hl7.fhir.dstu2016may.model.SampledData data = new org.hl7.fhir.dstu2016may.model.SampledData();
+ data.setData("1 2 3");
+ data.setOrigin((org.hl7.fhir.dstu2016may.model.SimpleQuantity) new org.hl7.fhir.dstu2016may.model.SimpleQuantity().setValue(0L));
+ data.setPeriod(1000L);
+ obs.setValue(data);
+
+ IParser p = ourCtx.newJsonParser().setPrettyPrint(true).setParserErrorHandler(new StrictErrorHandler());
+ String encoded = p.encodeResourceToString(obs);
+ ourLog.info(encoded);
+
+ p.parseResource(encoded);
+
+ try {
+ p.parseResource(encoded.replace("Observation", "observation"));
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Unknown resource type 'observation': Resource names are case sensitive, found similar name: 'Observation'", e.getMessage());
+ }
+
+ try {
+ p.parseResource(encoded.replace("valueSampledData", "valueSampleddata"));
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Unknown element 'valueSampleddata' found during parse", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testParseWithPrecision() {
+ String input = "{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.000000000000000100}}";
+ org.hl7.fhir.dstu2016may.model.Observation obs = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Observation.class, input);
+
+ org.hl7.fhir.dstu2016may.model.DecimalType valueElement = ((org.hl7.fhir.dstu2016may.model.Quantity) obs.getValue()).getValueElement();
+ assertEquals("0.000000000000000100", valueElement.getValueAsString());
+
+ String str = ourCtx.newJsonParser().encodeResourceToString(obs);
+ ourLog.info(str);
+ assertEquals("{\"resourceType\":\"Observation\",\"valueQuantity\":{\"value\":0.000000000000000100}}", str);
+ }
+
+ @Test(expected = DataFormatException.class)
+ public void testParseWithTrailingContent() throws Exception {
+ //@formatter:off
+ String bundle = "{\n" +
+ " \"resourceType\" : \"Bundle\",\n" +
+ " \"total\" : 1\n" +
+ "}}";
+ //@formatter:on
+
+ org.hl7.fhir.dstu2016may.model.Bundle b = ourCtx.newJsonParser().parseResource(org.hl7.fhir.dstu2016may.model.Bundle.class, bundle);
+ }
+
+ @Test
+ public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
+ String refVal = "http://my.org/FooBar";
+
+ org.hl7.fhir.dstu2016may.model.Patient fhirPat = new org.hl7.fhir.dstu2016may.model.Patient();
+ fhirPat.addExtension().setUrl("x1").setValue(new org.hl7.fhir.dstu2016may.model.Reference(refVal));
+
+ IParser parser = ourCtx.newJsonParser();
+
+ String output = parser.encodeResourceToString(fhirPat);
+ System.out.println("output: " + output);
+
+ // Deserialize then check that valueReference value is still correct
+ fhirPat = parser.parseResource(org.hl7.fhir.dstu2016may.model.Patient.class, output);
+
+ List extlst = fhirPat.getExtensionsByUrl("x1");
+ Assert.assertEquals(1, extlst.size());
+ Assert.assertEquals(refVal, ((org.hl7.fhir.dstu2016may.model.Reference) extlst.get(0).getValue()).getReference());
+ }
+
+
+ private Matcher super String> stringContainsInOrder(java.lang.String... substrings) {
+ return Matchers.stringContainsInOrder(Arrays.asList(substrings));
+ }
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/PatientWithExtendedContactDstu3.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/PatientWithExtendedContactDstu3.java
new file mode 100644
index 00000000000..186cac8e6a6
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/PatientWithExtendedContactDstu3.java
@@ -0,0 +1,60 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu21;
+
+import java.util.ArrayList;
+import java.util.List;
+import ca.uhn.fhir.model.api.annotation.Block;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.Description;
+import ca.uhn.fhir.model.api.annotation.Extension;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import org.hl7.fhir.dstu2016may.model.Identifier;
+import org.hl7.fhir.dstu2016may.model.Patient;
+
+@ResourceDef(name = "Patient")
+public class PatientWithExtendedContactDstu3 extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * A contact party (e.g. guardian, partner, friend) for the patient.
+ */
+ @Child(name = "contact", type = {}, order = Child.REPLACE_PARENT, min = 0, max = Child.MAX_UNLIMITED, modifier = false, summary = false)
+ @Description(shortDefinition = "A contact party (e.g. guardian, partner, friend) for the patient", formalDefinition = "A contact party (e.g. guardian, partner, friend) for the patient.")
+ protected List customContact;
+
+ public List getCustomContact() {
+ if (customContact == null) {
+ customContact = new ArrayList();
+ }
+ return customContact;
+ }
+
+ @Block()
+ public static class CustomContactComponent extends ContactComponent {
+
+ private static final long serialVersionUID = 1L;
+ @Child(name = "contact-eyecolour", type = { Identifier.class }, modifier = true)
+ @Description(shortDefinition = "Application ID")
+ @Extension(url = "http://foo.com/contact-eyecolour", definedLocally = false, isModifier = false)
+ private Identifier myEyeColour;
+
+ /*
+ * Get messageHeaderApplicationId
+ */
+ public Identifier getEyeColour() {
+ if (myEyeColour == null) {
+ myEyeColour = new Identifier();
+ }
+ return myEyeColour;
+ }
+
+ /*
+ * Set messageHeaderApplicationId
+ */
+ public void setEyeColour(Identifier messageHeaderApplicationId) {
+ this.myEyeColour = messageHeaderApplicationId;
+ }
+
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/XmlParserDstu2_1Test.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/XmlParserDstu2_1Test.java
new file mode 100644
index 00000000000..25a4e0f3ee2
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu21/XmlParserDstu2_1Test.java
@@ -0,0 +1,2480 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu21;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.UUID;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.parser.DataFormatException;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.parser.LenientErrorHandler;
+import ca.uhn.fhir.parser.StrictErrorHandler;
+import ca.uhn.fhir.rest.api.Constants;
+import com.google.common.collect.Sets;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.core.StringContains;
+import org.hamcrest.text.StringContainsInOrder;
+import org.hl7.fhir.dstu2016may.model.Address;
+import org.hl7.fhir.dstu2016may.model.Appointment;
+import org.hl7.fhir.dstu2016may.model.AuditEvent;
+import org.hl7.fhir.dstu2016may.model.Binary;
+import org.hl7.fhir.dstu2016may.model.Bundle;
+import org.hl7.fhir.dstu2016may.model.CodeType;
+import org.hl7.fhir.dstu2016may.model.CodeableConcept;
+import org.hl7.fhir.dstu2016may.model.Coding;
+import org.hl7.fhir.dstu2016may.model.Condition;
+import org.hl7.fhir.dstu2016may.model.ContactPoint;
+import org.hl7.fhir.dstu2016may.model.DateTimeType;
+import org.hl7.fhir.dstu2016may.model.DateType;
+import org.hl7.fhir.dstu2016may.model.DiagnosticReport;
+import org.hl7.fhir.dstu2016may.model.DocumentManifest;
+import org.hl7.fhir.dstu2016may.model.Duration;
+import org.hl7.fhir.dstu2016may.model.Encounter;
+import org.hl7.fhir.dstu2016may.model.Enumerations;
+import org.hl7.fhir.dstu2016may.model.Extension;
+import org.hl7.fhir.dstu2016may.model.HumanName;
+import org.hl7.fhir.dstu2016may.model.IdType;
+import org.hl7.fhir.dstu2016may.model.Identifier;
+import org.hl7.fhir.dstu2016may.model.InstantType;
+import org.hl7.fhir.dstu2016may.model.Location;
+import org.hl7.fhir.dstu2016may.model.Medication;
+import org.hl7.fhir.dstu2016may.model.MedicationOrder;
+import org.hl7.fhir.dstu2016may.model.Observation;
+import org.hl7.fhir.dstu2016may.model.Organization;
+import org.hl7.fhir.dstu2016may.model.Patient;
+import org.hl7.fhir.dstu2016may.model.PrimitiveType;
+import org.hl7.fhir.dstu2016may.model.Quantity;
+import org.hl7.fhir.dstu2016may.model.Reference;
+import org.hl7.fhir.dstu2016may.model.Resource;
+import org.hl7.fhir.dstu2016may.model.SampledData;
+import org.hl7.fhir.dstu2016may.model.SimpleQuantity;
+import org.hl7.fhir.dstu2016may.model.StringType;
+import org.hl7.fhir.dstu2016may.model.UriType;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.xmlunit.builder.DiffBuilder;
+import org.xmlunit.builder.Input;
+import org.xmlunit.diff.ComparisonControllers;
+import org.xmlunit.diff.DefaultNodeMatcher;
+import org.xmlunit.diff.Diff;
+import org.xmlunit.diff.ElementSelectors;
+
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_DSTU2_1;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+
+
+/**
+ * Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class XmlParserDstu2_1Test {
+
+ private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserDstu2_1Test.class);
+ private FhirContext ourCtx = FhirContext.forDstu2_1();
+
+ @Configuration
+ public Option[] config() throws IOException {
+ return options(
+ KARAF.option(),
+ WRAP.option(),
+ HAPI_FHIR_DSTU2_1.option(),
+ mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
+ mavenBundle().groupId("org.xmlunit").artifactId("xmlunit-core").versionAsInProject(),
+ when(false)
+ .useOptions(
+ debugConfiguration("5005", true))
+ );
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnFhirContext() {
+ try {
+ String tmp = " ";
+ ourCtx.getParserOptions().setOverrideResourceIdWithBundleEntryFullUrl(false);
+ Bundle bundle = (Bundle) ourCtx.newXmlParser().parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ Patient o1 = (Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ } finally {
+ // ensure we cleanup ourCtx so other tests continue to work
+ ourCtx = null;
+ }
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnParser() {
+ try {
+ String tmp = " ";
+ Bundle bundle = (Bundle) ourCtx.newXmlParser().setOverrideResourceIdWithBundleEntryFullUrl(false).parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ Patient o1 = (Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ } finally {
+ // ensure we cleanup ourCtx so other tests continue to work
+ ourCtx = null;
+ }
+ }
+
+ /**
+ * See #414
+ */
+ @Test
+ public void testParseXmlExtensionWithoutUrl() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ IParser parser = ourCtx.newXmlParser();
+ parser.setParserErrorHandler(new LenientErrorHandler());
+ Patient parsed = (Patient) parser.parseResource(input);
+ assertEquals(1, parsed.getExtension().size());
+ assertEquals(null, parsed.getExtension().get(0).getUrl());
+ assertEquals("2011-01-02T11:13:15", ((PrimitiveType>)parsed.getExtension().get(0).getValue()).getValueAsString());
+
+ try {
+ parser = ourCtx.newXmlParser();
+ parser.setParserErrorHandler(new StrictErrorHandler());
+ parser.parseResource(input);
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Resource is missing required element 'url' in parent element 'extension'", e.getCause().getMessage());
+ }
+
+ }
+
+
+ /**
+ * See #414
+ */
+ @Test
+ public void testParseXmlModifierExtensionWithoutUrl() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ IParser parser = ourCtx.newXmlParser();
+ parser.setParserErrorHandler(new LenientErrorHandler());
+ Patient parsed = (Patient) parser.parseResource(input);
+ assertEquals(1, parsed.getModifierExtension().size());
+ assertEquals(null, parsed.getModifierExtension().get(0).getUrl());
+ assertEquals("2011-01-02T11:13:15", ((PrimitiveType>)parsed.getModifierExtension().get(0).getValue()).getValueAsString());
+
+ try {
+ parser = ourCtx.newXmlParser();
+ parser.setParserErrorHandler(new StrictErrorHandler());
+ parser.parseResource(input);
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("Resource is missing required element 'url' in parent element 'modifierExtension'", e.getCause().getMessage());
+ }
+
+ }
+
+ @Test
+ public void testEncodeChainedContainedResourcer() {
+ Organization gp = new Organization();
+ gp.setName("grandparent");
+
+ Organization parent = new Organization();
+ parent.setName("parent");
+ parent.getPartOf().setResource(gp);
+
+ Organization child = new Organization();
+ child.setName("child");
+ child.getPartOf().setResource(parent);
+
+ Patient patient = new Patient();
+ patient.getManagingOrganization().setResource(child);
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ patient = ourCtx.newXmlParser().parseResource(Patient.class, encoded);
+
+ child = (Organization) patient.getManagingOrganization().getResource();
+ assertEquals("child", child.getName());
+
+ parent = (Organization) child.getPartOf().getResource();
+ assertEquals("parent", parent.getName());
+
+ gp = (Organization) parent.getPartOf().getResource();
+ assertEquals("grandparent", gp.getName());
+ }
+
+ @Test
+ public void testBundleWithBinary() {
+ //@formatter:off
+ String bundle = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ Bundle b = ourCtx.newXmlParser().parseResource(Bundle.class, bundle);
+ assertEquals(1, b.getEntry().size());
+
+ Binary bin = (Binary) b.getEntry().get(0).getResource();
+ assertArrayEquals(new byte[] { 1, 2, 3, 4 }, bin.getContent());
+
+ }
+
+ @Test
+ public void testContainedResourceInExtensionUndeclared() {
+ Patient p = new Patient();
+ p.addName().addFamily("PATIENT");
+
+ Organization o = new Organization();
+ o.setName("ORG");
+ p.addExtension(new Extension("urn:foo", new Reference(o)));
+
+ String str = ourCtx.newXmlParser().encodeResourceToString(p);
+ ourLog.info(str);
+
+ p = ourCtx.newXmlParser().parseResource(Patient.class, str);
+ assertEquals("PATIENT", p.getName().get(0).getFamilyAsSingleString());
+
+ List exts = p.getExtensionsByUrl("urn:foo");
+ assertEquals(1, exts.size());
+ Reference rr = (Reference) exts.get(0).getValue();
+ o = (Organization) rr.getResource();
+ assertEquals("ORG", o.getName());
+ }
+
+ @Test
+ public void testDuration() {
+ Encounter enc = new Encounter();
+ Duration duration = new Duration();
+ duration.setUnit("day").setValue(123L);
+ enc.setLength(duration);
+
+ String str = ourCtx.newXmlParser().encodeResourceToString(enc);
+ ourLog.info(str);
+
+ assertThat(str, not(containsString("meta")));
+ assertThat(str, containsString(" "));
+ }
+
+ @Test
+ public void testEncodeAndParseBundleWithResourceRefs() {
+
+ Patient pt = new Patient();
+ pt.setId("patid");
+ pt.addName().addFamily("PATIENT");
+
+ Organization org = new Organization();
+ org.setId("orgid");
+ org.setName("ORG");
+ pt.getManagingOrganization().setResource(org);
+
+ Bundle bundle = new Bundle();
+ bundle.addEntry().setResource(pt);
+ bundle.addEntry().setResource(org);
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(bundle);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "",
+ "",
+ "",
+ " "
+ ));
+ //@formatter:on
+
+ bundle = ourCtx.newXmlParser().parseResource(Bundle.class, encoded);
+ pt = (Patient) bundle.getEntry().get(0).getResource();
+ org = (Organization) bundle.getEntry().get(1).getResource();
+
+ assertEquals("Organization/orgid", org.getIdElement().getValue());
+ assertEquals("Organization/orgid", pt.getManagingOrganization().getReferenceElement().getValue());
+ assertSame(org, pt.getManagingOrganization().getResource());
+ }
+
+ @Test
+ public void testEncodeAndParseContained() {
+ IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
+
+ // Create an organization, note that the organization does not have an ID
+ Organization org = new Organization();
+ org.getNameElement().setValue("Contained Test Organization");
+
+ // Create a patient
+ Patient patient = new Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
+
+ // Put the organization as a reference in the patient resource
+ patient.getManagingOrganization().setResource(org);
+
+ String encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, containsString(""));
+ assertThat(encoded, containsString(""));
+
+ // Create a bundle with just the patient resource
+ Bundle b = new Bundle();
+ b.addEntry().setResource(patient);
+
+ // Encode the bundle
+ encoded = xmlParser.encodeResourceToString(b);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "", " ")));
+ assertThat(encoded, containsString(""));
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", " ")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", " ", ""))));
+
+ // Re-parse the bundle
+ patient = (Patient) xmlParser.parseResource(xmlParser.encodeResourceToString(patient));
+ assertEquals("#1", patient.getManagingOrganization().getReference());
+
+ assertNotNull(patient.getManagingOrganization().getResource());
+ org = (Organization) patient.getManagingOrganization().getResource();
+ assertEquals("#1", org.getIdElement().getValue());
+ assertEquals("Contained Test Organization", org.getName());
+
+ // And re-encode a second time
+ encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "", " ", "")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", ""))));
+ assertThat(encoded, containsString(""));
+
+ // And re-encode once more, with the references cleared
+ patient.getContained().clear();
+ patient.getManagingOrganization().setReference((String) null);
+ encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "", " ", "")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", ""))));
+ assertThat(encoded, containsString(""));
+
+ // And re-encode once more, with the references cleared and a manually set local ID
+ patient.getContained().clear();
+ patient.getManagingOrganization().setReference((String) null);
+ patient.getManagingOrganization().getResource().setId(("#333"));
+ encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "", " ", "")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", ""))));
+
+ }
+
+ @Test
+ public void testEncodeAndParseContainedNonCustomTypes() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ Observation obs = new Observation();
+ obs.setStatus(Observation.ObservationStatus.FINAL);
+
+ DiagnosticReport dr = new DiagnosticReport();
+ dr.setStatus(DiagnosticReport.DiagnosticReportStatus.FINAL);
+ dr.addResult().setResource(obs);
+
+ IParser parser = ourCtx.newXmlParser();
+ parser.setPrettyPrint(true);
+
+ String output = parser.encodeResourceToString(dr);
+ ourLog.info(output);
+
+ //@formatter:off
+ assertThat(output,stringContainsInOrder(
+ "",
+ "",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ " ",
+ " "));
+ //@formatter:on
+
+ /*
+ * Now PARSE!
+ */
+
+ dr = (DiagnosticReport) parser.parseResource(output);
+ assertEquals(DiagnosticReport.DiagnosticReportStatus.FINAL, dr.getStatus());
+
+ assertEquals("#1", dr.getResult().get(0).getReference());
+ obs = (Observation) dr.getResult().get(0).getResource();
+ assertEquals(Observation.ObservationStatus.FINAL, obs.getStatus());
+
+ ourCtx = null;
+ }
+
+ @Test
+ public void testEncodeAndParseExtensionOnCode() {
+ Organization o = new Organization();
+ o.setName("ORG");
+ o.addExtension(new Extension("urn:foo", new CodeType("acode")));
+
+ String str = ourCtx.newXmlParser().encodeResourceToString(o);
+ ourLog.info(str);
+ assertThat(str, containsString(""));
+
+ o = ourCtx.newXmlParser().parseResource(Organization.class, str);
+
+ List exts = o.getExtensionsByUrl("urn:foo");
+ assertEquals(1, exts.size());
+ CodeType code = (CodeType) exts.get(0).getValue();
+ assertEquals("acode", code.getValue());
+
+ }
+
+
+ @Test
+ public void testEncodeAndParseExtensions() throws Exception {
+
+ Patient patient = new Patient();
+ patient.addIdentifier().setUse(Identifier.IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
+
+ Extension ext = new Extension();
+ ext.setUrl("http://example.com/extensions#someext");
+ ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
+ patient.addExtension(ext);
+
+ Extension parent = new Extension().setUrl("http://example.com#parent");
+ patient.addExtension(parent);
+ Extension child1 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
+ parent.addExtension(child1);
+ Extension child2 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value2"));
+ parent.addExtension(child2);
+
+ Extension modExt = new Extension();
+ modExt.setUrl("http://example.com/extensions#modext");
+ modExt.setValue(new DateType("1995-01-02"));
+ patient.addModifierExtension(modExt);
+
+ HumanName name = patient.addName();
+ name.addFamily("Blah");
+ StringType given = name.addGivenElement();
+ given.setValue("Joe");
+ Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given"));
+ given.addExtension(ext2);
+
+ StringType given2 = name.addGivenElement();
+ given2.setValue("Shmoe");
+ Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent");
+ given2.addExtension(given2ext);
+ given2ext.addExtension(new Extension().setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD")));
+
+ String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(output);
+
+ String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
+ assertThat(enc, containsString(" "));
+ assertThat(enc, containsString(" "));
+ assertThat(enc, containsString(
+ " "));
+ assertThat(enc, containsString(" "));
+ assertThat(enc, containsString(
+ " "));
+
+ /*
+ * Now parse this back
+ */
+
+ Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, enc);
+ ext = parsed.getExtension().get(0);
+ assertEquals("http://example.com/extensions#someext", ext.getUrl());
+ assertEquals("2011-01-02T11:13:15", ((DateTimeType) ext.getValue()).getValueAsString());
+
+ parent = patient.getExtension().get(1);
+ assertEquals("http://example.com#parent", parent.getUrl());
+ assertNull(parent.getValue());
+ child1 = parent.getExtension().get(0);
+ assertEquals("http://example.com#child", child1.getUrl());
+ assertEquals("value1", ((StringType) child1.getValue()).getValueAsString());
+ child2 = parent.getExtension().get(1);
+ assertEquals("http://example.com#child", child2.getUrl());
+ assertEquals("value2", ((StringType) child2.getValue()).getValueAsString());
+
+ modExt = parsed.getModifierExtension().get(0);
+ assertEquals("http://example.com/extensions#modext", modExt.getUrl());
+ assertEquals("1995-01-02", ((DateType) modExt.getValue()).getValueAsString());
+
+ name = parsed.getName().get(0);
+
+ ext2 = name.getGiven().get(0).getExtension().get(0);
+ assertEquals("http://examples.com#givenext", ext2.getUrl());
+ assertEquals("given", ((StringType) ext2.getValue()).getValueAsString());
+
+ given2ext = name.getGiven().get(1).getExtension().get(0);
+ assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
+ assertNull(given2ext.getValue());
+ Extension given2ext2 = given2ext.getExtension().get(0);
+ assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
+ assertEquals("CHILD", ((StringType) given2ext2.getValue()).getValue());
+
+ }
+
+ /**
+ * See #216
+ */
+ @Test
+ public void testEncodeAndParseIdentifierDstu2() {
+ IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
+
+ Patient patient = new Patient();
+ patient.addIdentifier().setSystem("SYS").setValue("VAL").setType(new CodeableConcept().addCoding(new Coding().setSystem("http://hl7.org/fhir/v2/0203").setCode("MR")));
+
+ String out = xmlParser.encodeResourceToString(patient);
+ ourLog.info(out);
+
+ //@formatter:off
+ assertThat(out, stringContainsInOrder("",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ " ",
+ "",
+ "",
+ " "));
+ //@formatter:on
+
+ patient = ourCtx.newXmlParser().parseResource(Patient.class, out);
+ assertEquals("http://hl7.org/fhir/v2/0203", patient.getIdentifier().get(0).getType().getCoding().get(0).getSystem());
+ assertEquals("MR", patient.getIdentifier().get(0).getType().getCoding().get(0).getCode());
+ }
+
+ /**
+ * See #347
+ */
+ @Test
+ public void testEncodeAndParseMedicationOrder() {
+ MedicationOrder mo = new MedicationOrder();
+ mo.getDateWrittenElement().setValueAsString("2015-10-05");
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(mo);
+ ourLog.info(encoded);
+
+ mo = ourCtx.newXmlParser().parseResource(MedicationOrder.class, encoded);
+ assertEquals("2015-10-05", mo.getDateWrittenElement().getValueAsString());
+ }
+
+ @Test
+ public void testEncodeAndParseMetaProfileAndTags() {
+ Patient p = new Patient();
+ p.addName().addFamily("FAMILY");
+
+ p.getMeta().addProfile("http://foo/Profile1");
+ p.getMeta().addProfile("http://foo/Profile2");
+
+ p.getMeta().addTag().setSystem("scheme1").setCode("term1").setDisplay("label1");
+ p.getMeta().addTag().setSystem("scheme2").setCode("term2").setDisplay("label2");
+
+ p.getMeta().addSecurity().setSystem("sec_scheme1").setCode("sec_term1").setDisplay("sec_label1");
+ p.getMeta().addSecurity().setSystem("sec_scheme2").setCode("sec_term2").setDisplay("sec_label2");
+
+ String enc = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+
+ //@formatter:off
+ assertThat(enc, stringContainsInOrder("",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "",
+ "",
+ "",
+ "",
+ " ",
+ " "));
+ //@formatter:on
+
+ Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, enc);
+ List gotLabels = parsed.getMeta().getProfile();
+ assertEquals(2, gotLabels.size());
+ UriType label = gotLabels.get(0);
+ assertEquals("http://foo/Profile1", label.getValue());
+ label = gotLabels.get(1);
+ assertEquals("http://foo/Profile2", label.getValue());
+
+ List tagList = parsed.getMeta().getTag();
+ assertEquals(2, tagList.size());
+ assertEquals("scheme1", tagList.get(0).getSystem());
+ assertEquals("term1", tagList.get(0).getCode());
+ assertEquals("label1", tagList.get(0).getDisplay());
+ assertEquals("scheme2", tagList.get(1).getSystem());
+ assertEquals("term2", tagList.get(1).getCode());
+ assertEquals("label2", tagList.get(1).getDisplay());
+
+ tagList = parsed.getMeta().getSecurity();
+ assertEquals(2, tagList.size());
+ assertEquals("sec_scheme1", tagList.get(0).getSystem());
+ assertEquals("sec_term1", tagList.get(0).getCode());
+ assertEquals("sec_label1", tagList.get(0).getDisplay());
+ assertEquals("sec_scheme2", tagList.get(1).getSystem());
+ assertEquals("sec_term2", tagList.get(1).getCode());
+ assertEquals("sec_label2", tagList.get(1).getDisplay());
+ }
+
+ @Test
+ public void testEncodeAndParseMetaProfiles() {
+ Patient p = new Patient();
+ p.addName().addFamily("FAMILY");
+
+ p.getMeta().addTag().setSystem("scheme1").setCode("term1").setDisplay("label1");
+ p.getMeta().addTag().setSystem("scheme2").setCode("term2").setDisplay("label2");
+
+ String enc = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+
+ //@formatter:off
+ assertThat(enc, stringContainsInOrder("",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "",
+ "",
+ "",
+ "",
+ " ",
+ " "));
+ //@formatter:on
+
+ Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, enc);
+ assertThat(parsed.getMeta().getProfile(), empty());
+
+ List tagList = parsed.getMeta().getTag();
+ assertEquals(2, tagList.size());
+ assertEquals("scheme1", tagList.get(0).getSystem());
+ assertEquals("term1", tagList.get(0).getCode());
+ assertEquals("label1", tagList.get(0).getDisplay());
+ assertEquals("scheme2", tagList.get(1).getSystem());
+ assertEquals("term2", tagList.get(1).getCode());
+ assertEquals("label2", tagList.get(1).getDisplay());
+ }
+
+ /**
+ * See #336
+ */
+ @Test
+ public void testEncodeAndParseNullPrimitiveWithExtensions() {
+
+ Patient p = new Patient();
+ p.setId("patid");
+ HumanName name = p.addName();
+ name.addGivenElement().setValue(null).setId("f0").addExtension(new Extension("http://foo", new StringType("FOOEXT0")));
+ name.addGivenElement().setValue("V1").setId("f1").addExtension((Extension) new Extension("http://foo", new StringType("FOOEXT1")).setId("ext1id"));
+ name.addGivenElement(); // this one shouldn't get encoded
+ name.addGivenElement().setValue(null).addExtension(new Extension("http://foo", new StringType("FOOEXT3")));
+ name.setId("nameid");
+
+ String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(output);
+
+ output = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(p);
+ String expected = " ";
+
+ ourLog.info("Expected: {}", expected);
+ ourLog.info("Actual : {}", output);
+
+ assertEquals(expected, output);
+
+ p = ourCtx.newXmlParser().parseResource(Patient.class, output);
+ assertEquals("patid", p.getIdElement().getIdPart());
+
+ name = p.getName().get(0);
+ assertEquals("nameid", name.getId());
+ assertEquals(3, name.getGiven().size());
+
+ assertEquals(null, name.getGiven().get(0).getValue());
+ assertEquals("V1", name.getGiven().get(1).getValue());
+ assertEquals(null, name.getGiven().get(2).getValue());
+
+ assertEquals("f0", name.getGiven().get(0).getId());
+ assertEquals("f1", name.getGiven().get(1).getId());
+ assertEquals(null, name.getGiven().get(2).getId());
+
+ assertEquals(1, name.getGiven().get(0).getExtension().size());
+ assertEquals("http://foo", name.getGiven().get(0).getExtension().get(0).getUrl());
+ assertEquals("FOOEXT0", ((StringType) name.getGiven().get(0).getExtension().get(0).getValue()).getValue());
+ assertEquals(null, name.getGiven().get(0).getExtension().get(0).getId());
+
+ assertEquals(1, name.getGiven().get(1).getExtension().size());
+ assertEquals("http://foo", name.getGiven().get(1).getExtension().get(0).getUrl());
+ assertEquals("FOOEXT1", ((StringType) name.getGiven().get(1).getExtension().get(0).getValue()).getValue());
+ assertEquals("ext1id", name.getGiven().get(1).getExtension().get(0).getId());
+
+ assertEquals(1, name.getGiven().get(2).getExtension().size());
+ assertEquals("http://foo", name.getGiven().get(2).getExtension().get(0).getUrl());
+ assertEquals("FOOEXT3", ((StringType) name.getGiven().get(2).getExtension().get(0).getValue()).getValue());
+ assertEquals(null, name.getGiven().get(2).getExtension().get(0).getId());
+
+ }
+
+
+
+
+ @Test
+ public void testEncodeAndParseSecurityLabels() {
+ Patient p = new Patient();
+ p.addName().addFamily("FAMILY");
+
+ List labels = new ArrayList();
+ labels.add(new Coding().setSystem("SYSTEM1").setCode("CODE1").setDisplay("DISPLAY1").setVersion("VERSION1"));
+ labels.add(new Coding().setSystem("SYSTEM2").setCode("CODE2").setDisplay("DISPLAY2").setVersion("VERSION2"));
+ p.getMeta().getSecurity().addAll(labels);
+
+ String enc = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(enc);
+
+ //@formatter:off
+ assertThat(enc, stringContainsInOrder("",
+ " ",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ "",
+ "",
+ "",
+ " ",
+ " "));
+ //@formatter:on
+
+ Patient parsed = ourCtx.newXmlParser().parseResource(Patient.class, enc);
+ List gotLabels = parsed.getMeta().getSecurity();
+
+ assertEquals(2, gotLabels.size());
+
+ Coding label = gotLabels.get(0);
+ assertEquals("SYSTEM1", label.getSystem());
+ assertEquals("CODE1", label.getCode());
+ assertEquals("DISPLAY1", label.getDisplay());
+ assertEquals("VERSION1", label.getVersion());
+
+ label = gotLabels.get(1);
+ assertEquals("SYSTEM2", label.getSystem());
+ assertEquals("CODE2", label.getCode());
+ assertEquals("DISPLAY2", label.getDisplay());
+ assertEquals("VERSION2", label.getVersion());
+ }
+
+
+ @Test
+ public void testEncodeBinaryWithNoContentType() {
+ Binary b = new Binary();
+ b.setContent(new byte[] { 1, 2, 3, 4 });
+
+ String output = ourCtx.newXmlParser().encodeResourceToString(b);
+ ourLog.info(output);
+
+ assertEquals(" ", output);
+ }
+
+ @Test
+ public void testEncodeBundleWithContained() {
+ DiagnosticReport rpt = new DiagnosticReport();
+ rpt.addResult().setResource(new Observation().setCode(new CodeableConcept().setText("Sharp1")).setId("#1"));
+ rpt.addResult().setResource(new Observation().setCode(new CodeableConcept().setText("Uuid1")).setId("urn:uuid:UUID1"));
+
+ Bundle b = new Bundle();
+ b.addEntry().setResource(rpt);
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
+ ourLog.info(encoded);
+
+ assertThat(encoded, stringContainsInOrder("",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ "",
+ " "
+ ));
+ //@formatter:on
+ }
+
+ /**
+ * See #113
+ */
+ @Test
+ public void testEncodeContainedResources() {
+
+ MedicationOrder medicationPrescript = new MedicationOrder();
+
+ String medId = "123";
+ CodeableConcept codeDt = new CodeableConcept().addCoding(new Coding().setSystem("urn:sys").setCode("code1"));
+
+ // Adding medication to Contained.
+ Medication medResource = new Medication();
+ medResource.setCode(codeDt);
+ medResource.setId("#" + String.valueOf(medId));
+ medicationPrescript.getContained().add(medResource);
+
+ // Medication reference. This should point to the contained resource.
+ Reference medRefDt = new Reference("#" + medId);
+ medRefDt.setDisplay("MedRef");
+ medicationPrescript.setMedication(medRefDt);
+
+ IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
+ String encoded = p.encodeResourceToString(medicationPrescript);
+ ourLog.info(encoded);
+
+ // @formatter:on
+ assertThat(encoded,
+ stringContainsInOrder("", "", "", "", "", "",
+ "", "", "
", "
", " ", " ", "", "",
+ "", " ", " "));
+ //@formatter:off
+
+ }
+
+ /**
+ * See #113
+ */
+ @Test
+ public void testEncodeContainedResourcesAutomatic() {
+
+ MedicationOrder medicationPrescript = new MedicationOrder();
+ String nameDisp = "MedRef";
+ CodeableConcept codeDt = new CodeableConcept().addCoding(new Coding("urn:sys", "code1", null));
+
+ // Adding medication to Contained.
+ Medication medResource = new Medication();
+ // No ID set
+ medResource.setCode(codeDt);
+
+ // Medication reference. This should point to the contained resource.
+ Reference medRefDt = new Reference();
+ medRefDt.setDisplay(nameDisp);
+ // Resource reference set, but no ID
+ medRefDt.setResource(medResource);
+ medicationPrescript.setMedication(medRefDt);
+
+ IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
+ String encoded = p.encodeResourceToString(medicationPrescript);
+ ourLog.info(encoded);
+
+ //@formatter:on
+ assertThat(encoded,
+ stringContainsInOrder("", "", "", "", "", "",
+ "", "", "
", "
", " ", " ", "", "",
+ "", " ", " "));
+ //@formatter:off
+ }
+
+ /**
+ * See #113
+ */
+ @Test
+ public void testEncodeContainedResourcesManualContainUsingNonLocalId() {
+
+ MedicationOrder medicationPrescript = new MedicationOrder();
+
+ String medId = "123";
+ CodeableConcept codeDt = new CodeableConcept().addCoding(new Coding("urn:sys", "code1", null));
+
+ // Adding medication to Contained.
+ Medication medResource = new Medication();
+ medResource.setCode(codeDt);
+ medResource.setId(String.valueOf(medId)); // ID does not start with '#'
+ medicationPrescript.getContained().add(medResource);
+
+ // Medication reference. This should point to the contained resource.
+ Reference medRefDt = new Reference("#" + medId);
+ medRefDt.setDisplay("MedRef");
+ medicationPrescript.setMedication(medRefDt);
+
+ IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
+ String encoded = p.encodeResourceToString(medicationPrescript);
+ ourLog.info(encoded);
+
+ //@formatter:on
+ assertThat(encoded,
+ stringContainsInOrder("", "", "", "", "", "",
+ "", "", "
", "
", " ", " ", "", "",
+ "", " ", " "));
+ //@formatter:off
+
+ }
+
+ @Test
+ public void testEncodeContainedWithNarrativeIsSuppresed() throws Exception {
+ IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
+
+ // Create an organization, note that the organization does not have an ID
+ Organization org = new Organization();
+ org.getNameElement().setValue("Contained Test Organization");
+ org.getText().setDivAsString("FOOBAR
");
+
+ // Create a patient
+ Patient patient = new Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
+ patient.getText().setDivAsString("BARFOO
");
+ patient.getManagingOrganization().setResource(org);
+
+ String encoded = parser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, stringContainsInOrder("", "BARFOO
", "", "", "", "\n\nA P TAG
line1\nline2\nline3 BOLD ");
+
+ String output = ourCtx.newXmlParser().setPrettyPrint(false).encodeResourceToString(p);
+ ourLog.info(output);
+
+ //@formatter:off
+ assertThat(output, stringContainsInOrder(
+ "A P TAG
",
+ "
line1\nline2\nline3 BOLD "
+ ));
+ //@formatter:on
+
+ }
+
+ @Test
+ public void testEncodeDivWithPrePrettyPrint() {
+
+ Patient p = new Patient();
+ p.getText().setDivAsString("
\n\n
A P TAG
line1\nline2\nline3 BOLD ");
+
+ String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(output);
+
+ //@formatter:off
+ assertThat(output, stringContainsInOrder(
+ "
",
+ " line1\nline2\nline3
BOLD "
+ ));
+ //@formatter:on
+
+ }
+
+ @Test
+ public void testEncodeDoesntIncludeUuidId() {
+ Patient p = new Patient();
+ p.setId(new IdType("urn:uuid:42795ed8-041f-4ebf-b6f4-78ef6f64c2f2"));
+ p.addIdentifier().setSystem("ACME");
+
+ String actual = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
+ assertThat(actual, not(containsString("78ef6f64c2f2")));
+ }
+
+ @Test
+ public void testEncodeEmptyBinary() {
+ String output = ourCtx.newXmlParser().encodeResourceToString(new Binary());
+ assertEquals("
", output);
+ }
+
+ /**
+ * #158
+ */
+ @Test
+ public void testEncodeEmptyTag() {
+ ArrayList tagList = new ArrayList();
+ tagList.add(new Coding());
+ tagList.add(new Coding().setDisplay("Label"));
+
+ Patient p = new Patient();
+ p.getMeta().getTag().addAll(tagList);
+
+ String encoded = ourCtx.newXmlParser().encodeResourceToString(p);
+ assertThat(encoded, not(containsString("tag")));
+ }
+
+ /**
+ * #158
+ */
+ @Test
+ public void testEncodeEmptyTag2() {
+ ArrayList tagList = new ArrayList();
+ tagList.add(new Coding().setSystem("scheme").setCode("code"));
+ tagList.add(new Coding().setDisplay("Label"));
+
+ Patient p = new Patient();
+ p.getMeta().getTag().addAll(tagList);
+
+ String encoded = ourCtx.newXmlParser().encodeResourceToString(p);
+ assertThat(encoded, containsString("tag"));
+ assertThat(encoded, containsString("scheme"));
+ assertThat(encoded, not(containsString("Label")));
+ }
+
+ @Test
+ public void testEncodeExtensionUndeclaredNonModifier() {
+ Observation obs = new Observation();
+ obs.setId("1");
+ obs.getMeta().addProfile("http://profile");
+ Extension ext = obs.addExtension();
+ ext.setUrl("http://exturl").setValue(new StringType("ext_url_value"));
+
+ obs.getCode().setText("CODE");
+
+ IParser parser = ourCtx.newXmlParser();
+
+ String output = parser.setPrettyPrint(true).encodeResourceToString(obs);
+ ourLog.info(output);
+
+ //@formatter:off
+ assertThat(output, stringContainsInOrder(
+ "",
+ " ",
+ "",
+ "",
+ "",
+ ""
+ ));
+ assertThat(output, not(stringContainsInOrder(
+ ""
+ )));
+ //@formatter:on
+
+ obs = parser.parseResource(Observation.class, output);
+ assertEquals(1, obs.getExtension().size());
+ assertEquals("http://exturl", obs.getExtension().get(0).getUrl());
+ assertEquals("ext_url_value", ((StringType) obs.getExtension().get(0).getValue()).getValue());
+ }
+
+ @Test
+ public void testEncodeExtensionUndeclaredNonModifierWithChildExtension() {
+ Observation obs = new Observation();
+ obs.setId("1");
+ obs.getMeta().addProfile("http://profile");
+ Extension ext = obs.addExtension();
+ ext.setUrl("http://exturl");
+
+ Extension subExt = ext.addExtension();
+ subExt.setUrl("http://subext").setValue(new StringType("sub_ext_value"));
+
+ obs.getCode().setText("CODE");
+
+ IParser parser = ourCtx.newXmlParser();
+
+ String output = parser.setPrettyPrint(true).encodeResourceToString(obs);
+ ourLog.info(output);
+
+ //@formatter:off
+ assertThat(output, stringContainsInOrder(
+ "",
+ " ",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ));
+ assertThat(output, not(stringContainsInOrder(
+ ""
+ )));
+ //@formatter:on
+
+ obs = parser.parseResource(Observation.class, output);
+ assertEquals(1, obs.getExtension().size());
+ assertEquals("http://exturl", obs.getExtension().get(0).getUrl());
+ assertEquals(1, obs.getExtension().get(0).getExtension().size());
+ assertEquals("http://subext", obs.getExtension().get(0).getExtension().get(0).getUrl());
+ assertEquals("sub_ext_value", ((StringType) obs.getExtension().get(0).getExtension().get(0).getValue()).getValue());
+ }
+
+ /**
+ * See #327
+ */
+ @Test
+ public void testEncodeExtensionWithContainedResource() {
+
+ TestPatientFor327 patient = new TestPatientFor327();
+ patient.setBirthDateElement(new DateType("2016-04-14"));
+
+ List conditions = new ArrayList();
+ Condition condition = new Condition();
+ condition.addBodySite().setText("BODY SITE");
+ conditions.add(new Reference(condition));
+ patient.setCondition(conditions);
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "",
+ "",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ "",
+ " "
+ ));
+ //@formatter:on
+ }
+
+ @Test
+ public void testEncodeExtensionWithResourceContent() {
+ IParser parser = ourCtx.newXmlParser();
+
+ Patient patient = new Patient();
+ patient.addAddress().setUse(Address.AddressUse.HOME);
+ patient.addExtension(new Extension("urn:foo", new Reference("Organization/123")));
+
+ String val = parser.encodeResourceToString(patient);
+ ourLog.info(val);
+ assertThat(val, StringContains.containsString(" "));
+
+ Patient actual = parser.parseResource(Patient.class, val);
+ assertEquals(Address.AddressUse.HOME, patient.getAddress().get(0).getUse());
+ List ext = actual.getExtension();
+ assertEquals(1, ext.size());
+ Reference ref = (Reference) ext.get(0).getValue();
+ assertEquals("Organization/123", ref.getReference());
+
+ }
+
+ @Test
+ public void testEncodeHistoryEncodeVersionsAtPath3() {
+ ourCtx = FhirContext.forDstu2_1();
+
+ assertNull(ourCtx.newXmlParser().getStripVersionsFromReferences());
+
+ AuditEvent auditEvent = new AuditEvent();
+ auditEvent.addEntity().setReference(new Reference("http://foo.com/Organization/2/_history/1"));
+
+ IParser parser = ourCtx.newXmlParser();
+
+ parser.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference");
+ String enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString(""));
+
+ parser.setDontStripVersionsFromReferencesAtPaths(new ArrayList());
+ enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString(""));
+
+ parser.setDontStripVersionsFromReferencesAtPaths((String[]) null);
+ enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString(""));
+
+ parser.setDontStripVersionsFromReferencesAtPaths((List) null);
+ enc = parser.setPrettyPrint(true).encodeResourceToString(auditEvent);
+ ourLog.info(enc);
+ assertThat(enc, containsString(""));
+
+ }
+
+ @Test
+ public void testEncodeNarrativeSuppressed() {
+ Patient patient = new Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.setMaritalStatus(new CodeableConcept().addCoding(new Coding().setCode("D")));
+ patient.setMaritalStatus(new CodeableConcept().addCoding(new Coding().setCode("D")));
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).setSuppressNarratives(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("", " ", "
", ""));
+ assertThat(encoded, not(containsString("text")));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, containsString("maritalStatus"));
+ }
+
+ @Test
+ public void testEncodeNonContained() {
+ // Create an organization
+ Organization org = new Organization();
+ org.setId("Organization/65546");
+ org.getNameElement().setValue("Contained Test Organization");
+
+ // Create a patient
+ Patient patient = new Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
+ patient.getManagingOrganization().setResource(org);
+
+ // Create a list containing both resources. In a server method, you might just
+ // return this list, but here we will create a bundle to encode.
+ List resources = new ArrayList();
+ resources.add(org);
+ resources.add(patient);
+
+ // Create a bundle with both
+ Bundle b = new Bundle();
+ b.addEntry().setResource(org);
+ b.addEntry().setResource(patient);
+
+ // Encode the buntdle
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
+ ourLog.info(encoded);
+ assertThat(encoded, not(containsString("")));
+ assertThat(encoded, stringContainsInOrder("", " "));
+ assertThat(encoded, containsString(""));
+ assertThat(encoded, stringContainsInOrder("", " "));
+
+ encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, not(containsString("")));
+ assertThat(encoded, containsString(""));
+
+ }
+
+
+
+
+
+ @Test
+ public void testEncodeReferenceUsingUnqualifiedResourceWorksCorrectly() {
+
+ Patient patient = new Patient();
+ patient.setId("phitcc_pat_normal");
+ patient.addName().addGiven("Patty").setUse(HumanName.NameUse.NICKNAME);
+ patient.addTelecom().setSystem(ContactPoint.ContactPointSystem.EMAIL).setValue("patpain@ehealthinnovation.org");
+ patient.setGender(Enumerations.AdministrativeGender.FEMALE);
+ patient.setBirthDateElement(new DateType("2001-10-13"));
+
+ DateTimeType obsEffectiveTime = new DateTimeType("2015-04-11T12:22:01-04:00");
+
+ Observation obsParent = new Observation();
+ obsParent.setId("phitcc_obs_bp_parent");
+ obsParent.getSubject().setResource(patient);
+ obsParent.setStatus(Observation.ObservationStatus.FINAL);
+ obsParent.setEffective(obsEffectiveTime);
+
+ Observation obsSystolic = new Observation();
+ obsSystolic.setId("phitcc_obs_bp_dia");
+ obsSystolic.getSubject().setResource(patient);
+ obsSystolic.setEffective(obsEffectiveTime);
+ obsParent.addRelated().setType(Observation.ObservationRelationshipType.HASMEMBER).setTarget(new Reference(obsSystolic));
+
+ Observation obsDiastolic = new Observation();
+ obsDiastolic.setId("phitcc_obs_bp_dia");
+ obsDiastolic.getSubject().setResource(patient);
+ obsDiastolic.setEffective(obsEffectiveTime);
+ obsParent.addRelated().setType(Observation.ObservationRelationshipType.HASMEMBER).setTarget(new Reference(obsDiastolic));
+
+ String str = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(obsParent);
+ ourLog.info(str);
+
+ assertThat(str, containsString(""));
+ assertThat(str, containsString(""));
+ }
+
+
+ @Test
+ public void testEncodeSummary() {
+ Patient patient = new Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.setMaritalStatus(new CodeableConcept().addCoding(new Coding().setCode("D")));
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).setSummaryMode(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("", " ", "
", ""));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, not(containsString("maritalStatus")));
+ }
+
+ @Test
+ public void testEncodeSummary2() {
+ Patient patient = new Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.setMaritalStatus(new CodeableConcept().addCoding(new Coding().setCode("D")));
+
+ patient.getMeta().addTag().setSystem("foo").setCode("bar");
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).setSummaryMode(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("", "", "", ""));
+ assertThat(encoded, stringContainsInOrder("", " ", "
", " "));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, not(containsString("maritalStatus")));
+ }
+
+ @Test
+ public void testEncodeWithContained() {
+ List contained = new ArrayList();
+
+ // Will be added by reference
+ Patient p = new Patient();
+ p.setId("#" + "1000");
+ contained.add(p);
+
+ // Will be added by direct resource object
+ Location l = new Location();
+ l.setId("#" + "1001");
+ contained.add(l);
+
+ // Will not be referred to (and therefore shouldn't appear in output)
+ Location l2 = new Location();
+ l2.setId("#1002");
+ contained.add(l2);
+
+ Appointment appointment = new Appointment();
+ appointment.setId("1234");
+ appointment.getContained().addAll(contained);
+
+ appointment.addParticipant().getActor().setReference("#1000");
+ appointment.addParticipant().getActor().setResource(l);
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(appointment);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "",
+ "",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ " "
+ ));
+ //@formatter:on
+
+ assertThat(encoded, not(containsString("#1002")));
+ }
+
+ @Test
+ public void testEncodeWithDontEncodeElements() throws Exception {
+ Patient patient = new Patient();
+ patient.setId("123");
+ patient.getMeta().addProfile("http://profile");
+ patient.addName().addFamily("FAMILY").addGiven("GIVEN");
+ patient.addAddress().addLine("LINE1");
+
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setDontEncodeElements(Sets.newHashSet("*.meta", "*.id"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("address"));
+ assertThat(out, not(containsString("id")));
+ assertThat(out, not(containsString("meta")));
+ }
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setDontEncodeElements(Sets.newHashSet("Patient.meta", "Patient.id"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("address"));
+ assertThat(out, not(containsString("id")));
+ assertThat(out, not(containsString("meta")));
+ }
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setDontEncodeElements(Sets.newHashSet("Patient.name.family"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("GIVEN"));
+ assertThat(out, not(containsString("FAMILY")));
+ }
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setDontEncodeElements(Sets.newHashSet("*.meta", "*.id"));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("address"));
+ assertThat(out, not(containsString("id")));
+ assertThat(out, not(containsString("meta")));
+ }
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setDontEncodeElements(Sets.newHashSet("Patient.meta"));
+ p.setEncodeElements(new HashSet(Arrays.asList("Patient.name")));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(patient);
+ ourLog.info(out);
+ assertThat(out, containsString("Patient"));
+ assertThat(out, containsString("name"));
+ assertThat(out, containsString("id"));
+ assertThat(out, not(containsString("address")));
+ assertThat(out, not(containsString("meta")));
+ }
+ }
+
+ @Test
+ public void testEncodeWithEncodeElements() throws Exception {
+ Patient patient = new Patient();
+ patient.getMeta().addProfile("http://profile");
+ patient.addName().addFamily("FAMILY");
+ patient.addAddress().addLine("LINE1");
+
+ Bundle bundle = new Bundle();
+ bundle.setTotal(100);
+ bundle.addEntry().setResource(patient);
+
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setEncodeElements(new HashSet(Arrays.asList("Patient.name", "Bundle.entry")));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(bundle);
+ ourLog.info(out);
+ assertThat(out, not(containsString("total")));
+ assertThat(out, (containsString("Patient")));
+ assertThat(out, (containsString("name")));
+ assertThat(out, not(containsString("address")));
+ }
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setEncodeElements(new HashSet(Arrays.asList("Patient.name")));
+ p.setEncodeElementsAppliesToResourceTypes(new HashSet(Arrays.asList("Patient")));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(bundle);
+ ourLog.info(out);
+ assertThat(out, (containsString("total")));
+ assertThat(out, (containsString("Patient")));
+ assertThat(out, (containsString("name")));
+ assertThat(out, not(containsString("address")));
+ }
+ {
+ IParser p = ourCtx.newXmlParser();
+ p.setEncodeElements(new HashSet(Arrays.asList("Patient")));
+ p.setEncodeElementsAppliesToResourceTypes(new HashSet(Arrays.asList("Patient")));
+ p.setPrettyPrint(true);
+ String out = p.encodeResourceToString(bundle);
+ ourLog.info(out);
+ assertThat(out, (containsString("total")));
+ assertThat(out, (containsString("Patient")));
+ assertThat(out, (containsString("name")));
+ assertThat(out, (containsString("address")));
+ }
+
+ }
+
+ @Test
+ public void testMoreExtensions() throws Exception {
+
+ Patient patient = new Patient();
+ patient.addIdentifier().setUse(Identifier.IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
+
+ Extension ext = new Extension();
+ ext.setUrl("http://example.com/extensions#someext");
+ ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
+
+ // Add the extension to the resource
+ patient.addExtension(ext);
+ // END SNIPPET: resourceExtension
+
+ // START SNIPPET: resourceStringExtension
+ HumanName name = patient.addName();
+ name.addFamily("Shmoe");
+ StringType given = name.addGivenElement();
+ given.setValue("Joe");
+ Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given"));
+ given.addExtension(ext2);
+
+ StringType given2 = name.addGivenElement();
+ given2.setValue("Shmoe");
+ Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent");
+ given2.addExtension(given2ext);
+ Extension givenExtChild = new Extension();
+ givenExtChild.setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD"));
+ given2ext.addExtension(givenExtChild);
+ // END SNIPPET: resourceStringExtension
+
+ // START SNIPPET: subExtension
+ Extension parent = new Extension().setUrl("http://example.com#parent");
+ patient.addExtension(parent);
+
+ Extension child1 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
+ parent.addExtension(child1);
+
+ Extension child2 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
+ parent.addExtension(child2);
+ // END SNIPPET: subExtension
+
+ String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(output);
+
+ String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
+ assertThat(enc, containsString(" "));
+ assertThat(enc, containsString(
+ " "));
+ assertThat(enc, containsString(" "));
+ assertThat(enc, containsString(
+ " "));
+ }
+
+ @Test
+ public void testOmitResourceId() {
+ Patient p = new Patient();
+ p.setId("123");
+ p.addName().addFamily("ABC");
+
+ assertThat(ourCtx.newXmlParser().encodeResourceToString(p), stringContainsInOrder("123", "ABC"));
+ assertThat(ourCtx.newXmlParser().setOmitResourceId(true).encodeResourceToString(p), containsString("ABC"));
+ assertThat(ourCtx.newXmlParser().setOmitResourceId(true).encodeResourceToString(p), not(containsString("123")));
+ }
+
+
+ @Test
+ public void testParseAndEncodeComments() throws IOException {
+ //@formatter:off
+ String input = "\n" +
+ " " +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "\n" +
+ "
Patient Donald DUCK @ Acme Healthcare, Inc. MR = 654321
\n" +
+ "\n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " " +
+ " " +
+ " ";
+ //@formatter:off
+
+ Patient res = ourCtx.newXmlParser().parseResource(Patient.class, input);
+ res.getFormatCommentsPre();
+ assertEquals("Patient/pat1", res.getId());
+ assertEquals("654321", res.getIdentifier().get(0).getValue());
+ assertEquals(true, res.getActive());
+
+ assertThat(res.getIdElement().getFormatCommentsPre(), contains("pre resource comment"));
+ assertThat(res.getIdentifier().get(0).getFormatCommentsPre(), contains("identifier comment 1", "identifier comment 2"));
+ assertThat(res.getIdentifier().get(0).getUseElement().getFormatCommentsPre(), contains("use comment 1", "use comment 2"));
+ assertThat(res.getActiveElement().getFormatCommentsPost(), contains("post resource comment"));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(res);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "\"identifier\": [",
+ "{",
+ "\"fhir_comments\":",
+ "[",
+ "\"identifier comment 1\"",
+ ",",
+ "\"identifier comment 2\"",
+ "]",
+ "\"use\": \"usual\",",
+ "\"_use\": {",
+ "\"fhir_comments\":",
+ "[",
+ "\"use comment 1\"",
+ ",",
+ "\"use comment 2\"",
+ "]",
+ "},",
+ "\"type\""
+ ));
+ //@formatter:off
+
+ encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "",
+ "",
+ "",
+ "",
+ " ",
+ "
Patient Donald DUCK @ Acme Healthcare, Inc. MR = 654321
",
+ "
",
+ " ",
+ " \n",
+ " ",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "
",
+ " ",
+ "",
+ "",
+ " ",
+ "",
+ " "
+ ));
+ //@formatter:off
+
+ }
+
+ @Test
+ public void testParseAndEncodeCommentsOnExtensions() {
+ //@formatter:off
+ String input =
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+
+ Patient pat = ourCtx.newXmlParser().parseResource(Patient.class, input);
+ String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(pat);
+ ourLog.info(output);
+
+ assertThat(output, stringContainsInOrder(
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " "
+ ));
+
+ output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(pat);
+ ourLog.info(output);
+
+ assertThat(output, stringContainsInOrder(
+ "{",
+ " \"resourceType\": \"Patient\",",
+ " \"id\": \"someid\",",
+ " \"_id\": {",
+ " \"fhir_comments\": [",
+ " \" comment 1 \"",
+ " ]",
+ " },",
+ " \"extension\": [",
+ " {",
+ " \"fhir_comments\": [",
+ " \" comment 2 \",",
+ " \" comment 7 \"",
+ " ],",
+ " \"url\": \"urn:patientext:att\",",
+ " \"valueAttachment\": {",
+ " \"fhir_comments\": [",
+ " \" comment 3 \",",
+ " \" comment 6 \"",
+ " ],",
+ " \"contentType\": \"aaaa\",",
+ " \"_contentType\": {",
+ " \"fhir_comments\": [",
+ " \" comment 4 \"",
+ " ]",
+ " },",
+ " \"data\": \"AAAA\",",
+ " \"_data\": {",
+ " \"fhir_comments\": [",
+ " \" comment 5 \"",
+ " ]",
+ " }",
+ " }",
+ " }",
+ " ]",
+ "}"
+ ));
+
+ //@formatter:on
+ }
+
+
+ @Test
+ public void testParseAndEncodeNestedExtensions() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ Patient p = ourCtx.newXmlParser().parseResource(Patient.class, input);
+ DateType bd = p.getBirthDateElement();
+ assertEquals("2005-03-04", bd.getValueAsString());
+
+ List exts = bd.getExtensionsByUrl("http://my.fancy.extension.url");
+ assertEquals(1, exts.size());
+ Extension ext = exts.get(0);
+ assertEquals(null, ext.getValue());
+
+ exts = ext.getExtensionsByUrl("http://my.fancy.extension.url");
+ assertEquals(1, exts.size());
+ ext = exts.get(0);
+ assertEquals("myNestedValue", ((StringType) ext.getValue()).getValue());
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(p);
+ ourLog.info(encoded);
+
+ //@formatter:off
+ assertThat(encoded, stringContainsInOrder(
+ "",
+ "",
+ "",
+ "",
+ "",
+ " ",
+ " ",
+ " ",
+ " "));
+ //@formatter:on
+
+ }
+
+ @Test
+ public void testParseBundleNewWithPlaceholderIds() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n";
+ //@formatter:on
+
+ Bundle parsed = ourCtx.newXmlParser().parseResource(Bundle.class, input);
+ assertEquals("urn:oid:0.1.2.3", parsed.getEntry().get(0).getResource().getIdElement().getValue());
+
+ }
+
+ @Test
+ public void testParseBundleNewWithPlaceholderIdsInBase1() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n";
+ //@formatter:on
+
+ Bundle parsed = ourCtx.newXmlParser().parseResource(Bundle.class, input);
+ assertEquals("urn:oid:0.1.2.3", parsed.getEntry().get(0).getResource().getIdElement().getValue());
+ }
+
+ @Test
+ public void testParseBundleNewWithPlaceholderIdsInBase2() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n";
+ //@formatter:on
+
+ Bundle parsed = ourCtx.newXmlParser().parseResource(Bundle.class, input);
+ assertEquals("urn:uuid:0.1.2.3", parsed.getEntry().get(0).getResource().getIdElement().getValue());
+
+ //@formatter:off
+ input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n";
+ //@formatter:on
+
+ parsed = ourCtx.newXmlParser().parseResource(Bundle.class, input);
+ assertEquals("urn:uuid:0.1.2.3", parsed.getEntry().get(0).getResource().getIdElement().getValue());
+
+ }
+
+ @Test
+ public void testParseBundleOldStyleWithUnknownLinks() throws Exception {
+ //@formatter:off
+ String bundle = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ Bundle b = (Bundle) ourCtx.newXmlParser().parseResource(bundle);
+ assertEquals(1, b.getEntry().size());
+
+ }
+
+ @Test
+ public void testParseBundleOldWithPlaceholderIds() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n";
+ //@formatter:on
+
+ Bundle parsed = (Bundle) ourCtx.newXmlParser().parseResource(input);
+ assertEquals("urn:oid:0.1.2.3", parsed.getEntry().get(0).getResource().getId());
+
+ }
+
+ @Test
+ public void testParseBundleWithBinary() {
+ // TODO: implement this test, make sure we handle ID and meta correctly in Binary
+ }
+
+
+
+ @Test
+ public void testParseBundleWithResourceId() {
+ //@formatter:off
+ String input = ""
+ + " "
+ + " "
+ + " "
+ + " \n";
+ //@formatter:on
+
+ Bundle bundle = ourCtx.newXmlParser().parseResource(Bundle.class, input);
+ assertEquals("http://localhost:58402/fhir/context/Patient/1/_history/3", bundle.getEntry().get(0).getResource().getIdElement().getValue());
+ assertEquals("http://localhost:58402/fhir/context/Patient/1/_history/2", bundle.getEntry().get(1).getResource().getIdElement().getValue());
+ assertEquals("http://localhost:58402/fhir/context/Patient/1/_history/1", bundle.getEntry().get(2).getResource().getIdElement().getValue());
+ }
+
+ /**
+ * Thanks to Alexander Kley!
+ */
+ @Test
+ public void testParseContainedBinaryResource() {
+ byte[] bin = new byte[] { 0, 1, 2, 3, 4 };
+ final Binary binary = new Binary();
+ binary.setContentType("PatientConsent").setContent(bin);
+
+ DocumentManifest manifest = new DocumentManifest();
+ CodeableConcept cc = new CodeableConcept();
+ cc.addCoding().setSystem("mySystem").setCode("PatientDocument");
+ manifest.setType(cc);
+ manifest.setMasterIdentifier(new Identifier().setSystem("mySystem").setValue(UUID.randomUUID().toString()));
+ manifest.addContent().setP(new Reference(binary));
+ manifest.setStatus(Enumerations.DocumentReferenceStatus.CURRENT);
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(manifest);
+ ourLog.info(encoded);
+ assertThat(encoded, StringContainsInOrder.stringContainsInOrder(Arrays.asList("contained>", "")));
+
+ DocumentManifest actual = ourCtx.newXmlParser().parseResource(DocumentManifest.class, encoded);
+ assertEquals(1, actual.getContained().size());
+ assertEquals(1, actual.getContent().size());
+
+ /*
+ * If this fails, it's possibe the DocumentManifest structure is wrong: It should be
+ *
+ * @Child(name = "p", type = {Attachment.class, ValueSet.class}, order=1, min=1, max=1, modifier=false, summary=true)
+ */
+ assertNotNull(((Reference) actual.getContent().get(0).getP()).getResource());
+ }
+
+ /**
+ * See #426
+ */
+ @Test
+ public void testParseExtensionWithIdType() {
+ //@formatter:off
+ String input =
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+ Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, input);
+
+ List 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 =
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+ Patient pt = ourCtx.newXmlParser().parseResource(Patient.class, input);
+
+ List 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
+ */
+ @Test(expected = DataFormatException.class)
+ public void testParseInvalid() {
+ ourCtx.newXmlParser().parseResource("FOO");
+ }
+
+ /**
+ * See #366
+ */
+ @Test()
+ public void testParseInvalidBoolean() {
+ //@formatter:off
+ String resource = "\n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ IParser p = ourCtx.newXmlParser();
+
+ try {
+ p.parseResource(resource);
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Invalid attribute value \"1\": Invalid boolean string: '1'", e.getMessage());
+ }
+
+ LenientErrorHandler errorHandler = new LenientErrorHandler();
+ assertEquals(true, errorHandler.isErrorOnInvalidValue());
+ errorHandler.setErrorOnInvalidValue(false);
+ p.setParserErrorHandler(errorHandler);
+ }
+
+ @Test
+ public void testParseInvalidTextualNumber() {
+ Observation obs = new Observation();
+ obs.setValue(new Quantity().setValue(1234));
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs);
+ encoded = encoded.replace("1234", "\"1234\"");
+ ourLog.info(encoded);
+ ourCtx.newJsonParser().parseResource(encoded);
+ }
+
+ @Test
+ public void testParseMetadata() throws Exception {
+ //@formatter:off
+ String bundle = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ Bundle b = ourCtx.newXmlParser().parseResource(Bundle.class, bundle);
+ assertEquals(1, b.getEntry().size());
+
+ Bundle.BundleEntryComponent entry = b.getEntry().get(0);
+ Patient pt = (Patient) entry.getResource();
+ assertEquals("http://foo/fhirBase2/Patient/1/_history/2", pt.getIdElement().getValue());
+ assertEquals("2012-01-02", pt.getBirthDateElement().getValueAsString());
+ assertEquals("0.123", entry.getSearch().getScore().toString());
+ assertEquals("match", entry.getSearch().getMode().toCode());
+ assertEquals("POST", entry.getRequest().getMethod().toCode());
+ assertEquals("http://foo/Patient?identifier=value", entry.getRequest().getUrl());
+ assertEquals("2001-02-22T09:22:33-07:00", pt.getMeta().getLastUpdatedElement().getValueAsString());
+
+ IParser p = ourCtx.newXmlParser().setPrettyPrint(true);
+ String reEncoded = p.encodeResourceToString(b);
+ ourLog.info(reEncoded);
+
+ compareXml(bundle, reEncoded);
+
+ }
+
+ @Test
+ public void testParseMetaUpdatedDate() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+ Bundle b = ourCtx.newXmlParser().parseResource(Bundle.class, input);
+
+ InstantType updated = b.getMeta().getLastUpdatedElement();
+ assertEquals("2015-06-22T15:48:57.554-04:00", updated.getValueAsString());
+
+ }
+
+ @Test
+ public void testParseNestedExtensionsInvalid() {
+ //@formatter:off
+ String input = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " ";
+ //@formatter:on
+
+ try {
+ ourCtx.newXmlParser().parseResource(Patient.class, input);
+ fail();
+ } catch (DataFormatException e) {
+ assertThat(e.getMessage(), containsString("Extension (URL='http://my.fancy.extension.url') must not have both a value and other contained extensions"));
+ }
+ }
+
+ /**
+ * See #163
+ */
+ @Test
+ public void testParseResourceType() {
+ IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
+
+ // Patient
+ Patient patient = new Patient();
+ String patientId = UUID.randomUUID().toString();
+ patient.setId(new IdType("Patient", patientId));
+ patient.addName().addGiven("John").addFamily("Smith");
+ patient.setGender(Enumerations.AdministrativeGender.MALE);
+ patient.setBirthDateElement(new DateType("1987-04-16"));
+
+ // Bundle
+ Bundle bundle = new Bundle();
+ bundle.setType(Bundle.BundleType.COLLECTION);
+ bundle.addEntry().setResource(patient);
+
+ String bundleText = xmlParser.encodeResourceToString(bundle);
+ ourLog.info(bundleText);
+
+ Bundle reincarnatedBundle = xmlParser.parseResource(Bundle.class, bundleText);
+ Patient reincarnatedPatient = (Patient) reincarnatedBundle.getEntry().get(0).getResource();
+
+ assertEquals("Patient", patient.getIdElement().getResourceType());
+ assertEquals("Patient", reincarnatedPatient.getIdElement().getResourceType());
+ }
+
+ /**
+ * See #344
+ */
+ @Test
+ public void testParserIsCaseSensitive() {
+ Observation obs = new Observation();
+ SampledData data = new SampledData();
+ data.setData("1 2 3");
+ data.setOrigin((SimpleQuantity) new SimpleQuantity().setValue(0L));
+ data.setPeriod(1000L);
+ obs.setValue(data);
+
+ IParser p = ourCtx.newXmlParser().setPrettyPrint(true).setParserErrorHandler(new StrictErrorHandler());
+ String encoded = p.encodeResourceToString(obs);
+ ourLog.info(encoded);
+
+ p.parseResource(encoded);
+
+ try {
+ p.parseResource(encoded.replace("Observation", "observation"));
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("DataFormatException at [[row,col {unknown-source}]: [1,1]]: Unknown resource type 'observation': Resource names are case sensitive, found similar name: 'Observation'",
+ e.getMessage());
+ }
+
+ try {
+ p.parseResource(encoded.replace("valueSampledData", "valueSampleddata"));
+ fail();
+ } catch (DataFormatException e) {
+ assertEquals("DataFormatException at [[row,col {unknown-source}]: [2,4]]: Unknown element 'valueSampleddata' found during parse", e.getMessage());
+ }
+ }
+
+ /**
+ * See #339
+ *
+ * https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing
+ */
+ @Test
+ public void testXxe() {
+ //@formatter:off
+ String input =
+ "" +
+ "" +
+ "]>" +
+ "" +
+ "" +
+ "TEXT &xxe; TEXT
" +
+ " " +
+ "" +
+ "" +
+ " " +
+ " ";
+ //@formatter:on
+
+ ourLog.info(input);
+
+ try {
+ ourCtx.newXmlParser().parseResource(Patient.class, input);
+ fail();
+ } catch (DataFormatException e) {
+ assertThat(e.toString(), containsString("Undeclared general entity"));
+ }
+
+ }
+
+ @Test
+ public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
+ String refVal = "http://my.org/FooBar";
+
+ Patient fhirPat = new Patient();
+ fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
+
+ IParser parser = ourCtx.newXmlParser();
+
+ String output = parser.encodeResourceToString(fhirPat);
+ System.out.println("output: " + output);
+
+ // Deserialize then check that valueReference value is still correct
+ fhirPat = parser.parseResource(Patient.class, output);
+
+ List extlst = fhirPat.getExtensionsByUrl("x1");
+ Assert.assertEquals(1, extlst.size());
+ Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
+ }
+
+ public static void compareXml(String content, String reEncoded) {
+ Diff d = DiffBuilder.compare(Input.fromString(content))
+ .withTest(Input.fromString(reEncoded))
+ .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))
+ .checkForSimilar()
+ .ignoreWhitespace()
+ .ignoreComments()
+ .withComparisonController(ComparisonControllers.Default)
+ .build();
+
+ assertTrue(d.toString(), !d.hasDifferences());
+ }
+
+ @ResourceDef(name = "Patient")
+ public static class TestPatientFor327 extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(name = "testCondition")
+ @ca.uhn.fhir.model.api.annotation.Extension(url = "testCondition", definedLocally = true, isModifier = false)
+ private List testConditions = null;
+
+ public List getConditions() {
+ return this.testConditions;
+ }
+
+ public void setCondition(List ref) {
+ this.testConditions = ref;
+ }
+ }
+
+ private Matcher super String> stringContainsInOrder(java.lang.String... substrings) {
+ return Matchers.stringContainsInOrder(Arrays.asList(substrings));
+ }
+
+ private Matcher super String> stringContainsInOrder(List substrings) {
+ return Matchers.stringContainsInOrder(substrings);
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/FhirInstanceValidatorTest.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/FhirInstanceValidatorTest.java
new file mode 100644
index 00000000000..9adf2c836d9
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/FhirInstanceValidatorTest.java
@@ -0,0 +1,136 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import java.io.IOException;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.validation.FhirValidator;
+import ca.uhn.fhir.validation.ValidationResult;
+import org.hl7.fhir.instance.hapi.validation.DefaultProfileValidationSupport;
+import org.hl7.fhir.instance.hapi.validation.FhirInstanceValidator;
+import org.hl7.fhir.instance.model.DateType;
+import org.hl7.fhir.instance.model.Observation;
+import org.hl7.fhir.instance.model.QuestionnaireResponse;
+import org.hl7.fhir.instance.model.StringType;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_VALIDATION_HL7ORG_DSTU2;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+
+/**
+ * Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class FhirInstanceValidatorTest {
+ private FhirInstanceValidator ourValidator = new FhirInstanceValidator(new DefaultProfileValidationSupport());
+ private FhirContext ourCtxHl7OrgDstu2 = FhirContext.forDstu2Hl7Org();
+ private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirInstanceValidatorTest.class);
+
+ @Configuration
+ public Option[] config() throws IOException {
+ return options(
+ KARAF.option(),
+ WRAP.option(),
+ HAPI_FHIR_VALIDATION_HL7ORG_DSTU2.option(),
+ mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
+ when(false)
+ .useOptions(
+ debugConfiguration("5005", true))
+ );
+ }
+
+ @Test
+ public void testQuestionnaireResponse() {
+ QuestionnaireResponse qr = new QuestionnaireResponse();
+ qr.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
+ qr.getGroup().addGroup().addQuestion().setLinkId("foo");
+ qr.getGroup().addQuestion().setLinkId("bar");
+
+ FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
+
+ val.registerValidatorModule(ourValidator);
+
+ ValidationResult result = val.validateWithResult(qr);
+
+ String encoded = ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
+ ourLog.info(encoded);
+
+ assertTrue(result.isSuccessful());
+ }
+
+ @Test
+ public void testObservation() {
+ Observation o = new Observation();
+ o.addIdentifier().setSystem("http://acme.org").setValue("1234");
+ o.setStatus(Observation.ObservationStatus.FINAL);
+ o.getCode().addCoding().setSystem("http://loinc.org").setCode("12345");
+ o.getEncounter().setReference("Encounter/1234");
+
+ FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
+
+ val.registerValidatorModule(ourValidator);
+
+ ValidationResult result = val.validateWithResult(o);
+
+ String encoded = ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
+ ourLog.info(encoded);
+
+ assertTrue(result.isSuccessful());
+ }
+
+ @Test
+ public void testParametersWithTwoParameters() {
+ org.hl7.fhir.instance.model.Patient patient = new org.hl7.fhir.instance.model.Patient();
+ patient.addName().addGiven("James");
+ patient.setBirthDateElement(new DateType("2011-02-02"));
+
+ org.hl7.fhir.instance.model.Parameters input = new org.hl7.fhir.instance.model.Parameters();
+ input.addParameter().setName("mode").setValue(new StringType("create"));
+ input.addParameter().setName("resource").setResource(patient);
+
+ FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
+
+ val.registerValidatorModule(ourValidator);
+
+ ValidationResult result = val.validateWithResult(input);
+
+ String encoded = ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome());
+ ourLog.info(encoded);
+
+ assertTrue(result.isSuccessful());
+ assertThat(encoded, not(containsString("A parameter must have a value or a resource, but not both")));
+ }
+
+ @Test
+ public void testParametersHl7OrgDstu2() {
+ org.hl7.fhir.instance.model.Patient patient = new org.hl7.fhir.instance.model.Patient();
+ patient.addName().addGiven("James");
+ patient.setBirthDateElement(new DateType("2011-02-02"));
+
+ org.hl7.fhir.instance.model.Parameters input = new org.hl7.fhir.instance.model.Parameters();
+ input.addParameter().setName("resource").setResource(patient);
+
+ FhirValidator val = ourCtxHl7OrgDstu2.newValidator();
+
+ val.registerValidatorModule(ourValidator);
+
+ ValidationResult result = val.validateWithResult(input);
+
+ ourLog.info(ourCtxHl7OrgDstu2.newJsonParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()));
+ assertTrue(result.isSuccessful());
+ }
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/JsonParserHl7OrgDstu2Test.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/JsonParserHl7OrgDstu2Test.java
new file mode 100644
index 00000000000..28e98cd4656
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/JsonParserHl7OrgDstu2Test.java
@@ -0,0 +1,1320 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.narrative.INarrativeGenerator;
+import ca.uhn.fhir.parser.DataFormatException;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.rest.api.Constants;
+import org.apache.commons.io.IOUtils;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.core.IsNot;
+import org.hamcrest.core.StringContains;
+import org.hamcrest.text.StringContainsInOrder;
+import org.hl7.fhir.instance.model.Address;
+import org.hl7.fhir.instance.model.Address.AddressUse;
+import org.hl7.fhir.instance.model.Address.AddressUseEnumFactory;
+import org.hl7.fhir.instance.model.Binary;
+import org.hl7.fhir.instance.model.Bundle;
+import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
+import org.hl7.fhir.instance.model.CodeableConcept;
+import org.hl7.fhir.instance.model.Conformance;
+import org.hl7.fhir.instance.model.Conformance.UnknownContentCode;
+import org.hl7.fhir.instance.model.DateTimeType;
+import org.hl7.fhir.instance.model.DateType;
+import org.hl7.fhir.instance.model.DecimalType;
+import org.hl7.fhir.instance.model.DiagnosticReport;
+import org.hl7.fhir.instance.model.EnumFactory;
+import org.hl7.fhir.instance.model.Enumeration;
+import org.hl7.fhir.instance.model.Extension;
+import org.hl7.fhir.instance.model.HumanName;
+import org.hl7.fhir.instance.model.Identifier.IdentifierUse;
+import org.hl7.fhir.instance.model.InstantType;
+import org.hl7.fhir.instance.model.List_;
+import org.hl7.fhir.instance.model.Narrative.NarrativeStatus;
+import org.hl7.fhir.instance.model.Observation;
+import org.hl7.fhir.instance.model.Organization;
+import org.hl7.fhir.instance.model.Patient;
+import org.hl7.fhir.instance.model.Patient.ContactComponent;
+import org.hl7.fhir.instance.model.PrimitiveType;
+import org.hl7.fhir.instance.model.Reference;
+import org.hl7.fhir.instance.model.Specimen;
+import org.hl7.fhir.instance.model.StringType;
+import org.hl7.fhir.instance.model.ValueSet;
+import org.hl7.fhir.instance.model.ValueSet.ConceptDefinitionComponent;
+import org.hl7.fhir.instance.model.ValueSet.ValueSetCodeSystemComponent;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.instance.model.api.INarrative;
+import org.hl7.fhir.instance.model.api.IPrimitiveType;
+import org.hl7.fhir.utilities.xhtml.XhtmlNode;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.xml.sax.SAXException;
+
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_HL7ORG_DSTU2;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+
+/**
+ * Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class JsonParserHl7OrgDstu2Test {
+
+ private FhirContext ourCtx = FhirContext.forDstu2Hl7Org();
+ private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserHl7OrgDstu2Test.class);
+
+ @Configuration
+ public Option[] config() throws IOException {
+ return options(
+ KARAF.option(),
+ WRAP.option(),
+ HAPI_FHIR_HL7ORG_DSTU2.option(),
+ mavenBundle().groupId("org.xmlunit").artifactId("xmlunit-core").versionAsInProject(),
+ mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
+ when(false)
+ .useOptions(
+ debugConfiguration("5005", true))
+ );
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlEnabled() {
+ try {
+ String tmp = "{\"resourceType\":\"Bundle\",\"entry\":[{\"fullUrl\":\"http://lalaland.org/patient/pat1\",\"resource\":{\"resourceType\":\"Patient\",\"id\":\"patxuzos\"}}]}";
+ Bundle bundle = (Bundle) ourCtx.newJsonParser().parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ Patient o1 = (Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertEquals("http://lalaland.org", o1Id.getBaseUrl());
+ assertEquals("patient", o1Id.getResourceType());
+ assertEquals("pat1", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ } finally {
+ // ensure we cleanup ourCtx so other tests continue to work
+ ourCtx = FhirContext.forDstu2Hl7Org();
+ }
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnFhirContext() {
+ try {
+ String tmp = "{\"resourceType\":\"Bundle\",\"entry\":[{\"fullUrl\":\"http://lalaland.org/patient/pat1\",\"resource\":{\"resourceType\":\"Patient\",\"id\":\"patxuzos\"}}]}";
+ ourCtx.getParserOptions().setOverrideResourceIdWithBundleEntryFullUrl(false);
+ Bundle bundle = (Bundle) ourCtx.newJsonParser().parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ Patient o1 = (Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ } finally {
+ // ensure we cleanup ourCtx so other tests continue to work
+ ourCtx = FhirContext.forDstu2Hl7Org();
+ }
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnParser() {
+ try {
+ String tmp = "{\"resourceType\":\"Bundle\",\"entry\":[{\"fullUrl\":\"http://lalaland.org/patient/pat1\",\"resource\":{\"resourceType\":\"Patient\",\"id\":\"patxuzos\"}}]}";
+ Bundle bundle = (Bundle) ourCtx.newJsonParser().setOverrideResourceIdWithBundleEntryFullUrl(false).parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ Patient o1 = (Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ } finally {
+ // ensure we cleanup ourCtx so other tests continue to work
+ ourCtx = FhirContext.forDstu2Hl7Org();
+ }
+ }
+
+ @Test
+ public void testEncodeUndeclaredExtensionWithEnumerationContent() {
+ IParser parser = ourCtx.newJsonParser();
+
+ Patient patient = new Patient();
+ patient.addAddress().setUse(AddressUse.HOME);
+ EnumFactory fact = new AddressUseEnumFactory();
+ PrimitiveType enumeration = new Enumeration(fact).setValue(AddressUse.HOME);
+ patient.addExtension().setUrl("urn:foo").setValue(enumeration);
+
+ String val = parser.encodeResourceToString(patient);
+ ourLog.info(val);
+ assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueCode\":\"home\"}]"));
+
+ MyPatientWithOneDeclaredEnumerationExtension actual = parser.parseResource(MyPatientWithOneDeclaredEnumerationExtension.class, val);
+ assertEquals(AddressUse.HOME, patient.getAddress().get(0).getUse());
+ Enumeration ref = actual.getFoo();
+ assertEquals("home", ref.getValue().toCode());
+
+ }
+
+ @Test
+ public void testEncodeNarrativeSuppressed() throws Exception {
+ Patient patient = new Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.getMaritalStatus().addCoding().setCode("D");
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).setSuppressNarratives(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("Patient"));
+ assertThat(encoded, stringContainsInOrder(Constants.TAG_SUBSETTED_SYSTEM, Constants.TAG_SUBSETTED_CODE));
+ assertThat(encoded, not(containsString("text")));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, containsString("maritalStatus"));
+ }
+
+ @Test
+ public void testEncodeAndParseExtensions() throws Exception {
+
+ Patient patient = new Patient();
+ patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
+
+ Extension ext = new Extension();
+ ext.setUrl("http://example.com/extensions#someext");
+ ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
+ patient.getExtension().add(ext);
+
+ Extension parent = new Extension().setUrl("http://example.com#parent");
+ patient.getExtension().add(parent);
+ Extension child1 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
+ parent.getExtension().add(child1);
+ Extension child2 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value2"));
+ parent.getExtension().add(child2);
+
+ Extension modExt = new Extension();
+ modExt.setUrl("http://example.com/extensions#modext");
+ modExt.setValue(new DateType("1995-01-02"));
+ patient.getModifierExtension().add(modExt);
+
+ HumanName name = patient.addName();
+ name.addFamily("Blah");
+ StringType given = name.addGivenElement();
+ given.setValue("Joe");
+ Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given"));
+ given.getExtension().add(ext2);
+
+ StringType given2 = name.addGivenElement();
+ given2.setValue("Shmoe");
+ Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent");
+ given2.getExtension().add(given2ext);
+ given2ext.addExtension().setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD"));
+
+ String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(output);
+
+ String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
+ assertThat(enc,
+ stringContainsInOrder("{\"resourceType\":\"Patient\",", "\"extension\":[{\"url\":\"http://example.com/extensions#someext\",\"valueDateTime\":\"2011-01-02T11:13:15\"}",
+ "{\"url\":\"http://example.com#parent\",\"extension\":[{\"url\":\"http://example.com#child\",\"valueString\":\"value1\"},{\"url\":\"http://example.com#child\",\"valueString\":\"value2\"}]}"));
+ assertThat(enc, stringContainsInOrder("\"modifierExtension\":[" + "{" + "\"url\":\"http://example.com/extensions#modext\"," + "\"valueDate\":\"1995-01-02\"" + "}" + "],"));
+ assertThat(enc, containsString("\"_given\":[" + "{" + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext\"," + "\"valueString\":\"given\"" + "}" + "]" + "}," + "{"
+ + "\"extension\":[" + "{" + "\"url\":\"http://examples.com#givenext_parent\"," + "\"extension\":[" + "{"
+ + "\"url\":\"http://examples.com#givenext_child\"," + "\"valueString\":\"CHILD\"" + "}" + "]" + "}" + "]" + "}"));
+
+ /*
+ * Now parse this back
+ */
+
+ Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, enc);
+ ext = parsed.getExtension().get(0);
+ assertEquals("http://example.com/extensions#someext", ext.getUrl());
+ assertEquals("2011-01-02T11:13:15", ((DateTimeType) ext.getValue()).getValueAsString());
+
+ parent = patient.getExtension().get(1);
+ assertEquals("http://example.com#parent", parent.getUrl());
+ assertNull(parent.getValue());
+ child1 = parent.getExtension().get(0);
+ assertEquals("http://example.com#child", child1.getUrl());
+ assertEquals("value1", ((StringType) child1.getValue()).getValueAsString());
+ child2 = parent.getExtension().get(1);
+ assertEquals("http://example.com#child", child2.getUrl());
+ assertEquals("value2", ((StringType) child2.getValue()).getValueAsString());
+
+ modExt = parsed.getModifierExtension().get(0);
+ assertEquals("http://example.com/extensions#modext", modExt.getUrl());
+ assertEquals("1995-01-02", ((DateType) modExt.getValue()).getValueAsString());
+
+ name = parsed.getName().get(0);
+
+ ext2 = name.getGiven().get(0).getExtension().get(0);
+ assertEquals("http://examples.com#givenext", ext2.getUrl());
+ assertEquals("given", ((StringType) ext2.getValue()).getValueAsString());
+
+ given2ext = name.getGiven().get(1).getExtension().get(0);
+ assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
+ assertNull(given2ext.getValue());
+ Extension given2ext2 = given2ext.getExtension().get(0);
+ assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
+ assertEquals("CHILD", ((StringType) given2ext2.getValue()).getValue());
+
+ }
+
+ @Test
+ public void testEncodeBinaryResource() {
+
+ Binary patient = new Binary();
+ patient.setContentType("foo");
+ patient.setContent(new byte[] { 1, 2, 3, 4 });
+
+ String val = ourCtx.newJsonParser().encodeResourceToString(patient);
+ assertEquals("{\"resourceType\":\"Binary\",\"contentType\":\"foo\",\"content\":\"AQIDBA==\"}", val);
+
+ }
+
+ @Test
+ public void testEncodeBundle() throws InterruptedException {
+ Bundle b = new Bundle();
+
+ InstantType pub = InstantType.now();
+ b.getMeta().setLastUpdatedElement(pub);
+ Thread.sleep(2);
+
+ Patient p1 = new Patient();
+ p1.addName().addFamily("Family1");
+ p1.setId("1");
+ BundleEntryComponent entry = b.addEntry();
+ entry.setResource(p1);
+
+ Patient p2 = new Patient();
+ p2.setId("Patient/2");
+ p2.addName().addFamily("Family2");
+ entry = b.addEntry();
+ entry.setResource(p2);
+
+ BundleEntryComponent deletedEntry = b.addEntry();
+ Patient dp = new Patient();
+ deletedEntry.setResource(dp);
+
+ dp.setId(("3"));
+ InstantType nowDt = InstantType.withCurrentTime();
+ dp.getMeta().setLastUpdatedElement(nowDt);
+
+ String bundleString = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b);
+ ourLog.info(bundleString);
+
+ // List strings = new ArrayList();
+ // strings.addAll(Arrays.asList("\"published\":\"" + pub.getValueAsString() + "\""));
+ // strings.addAll(Arrays.asList("\"id\":\"1\""));
+ // strings.addAll(Arrays.asList("\"id\":\"2\"", "\"rel\":\"alternate\"", "\"href\":\"http://foo/bar\""));
+ // strings.addAll(Arrays.asList("\"deleted\":\"" + nowDt.getValueAsString() + "\"", "\"id\":\"Patient/3\""));
+
+ //@formatter:off
+ String[] strings = new String[] {
+ "\"resourceType\": \"Bundle\",",
+ "\"lastUpdated\": \"" + pub.getValueAsString() + "\"",
+ "\"entry\": [",
+ "\"resource\": {",
+ "\"id\": \"1\"",
+ "\"resource\": {",
+ "\"id\": \"2\"",
+ "\"resource\": {",
+ "\"id\": \"3\"",
+ "\"meta\": {",
+ "\"lastUpdated\": \"" + nowDt.getValueAsString() + "\""
+ };
+ //@formatter:off
+ assertThat(bundleString, StringContainsInOrder.stringContainsInOrder(Arrays.asList(strings)));
+
+ b.getEntry().remove(2);
+ bundleString = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b);
+ assertThat(bundleString, not(containsString("deleted")));
+
+ }
+
+
+ @Test
+ public void testEncodeBundleCategory() {
+
+ Bundle b = new Bundle();
+ BundleEntryComponent e = b.addEntry();
+
+ Patient pt = new Patient();
+ pt.addIdentifier().setSystem("idsystem");
+ e.setResource(pt);
+
+ b.getMeta().addTag().setSystem("scheme").setCode("term").setDisplay("label");
+
+ String val = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(b);
+ ourLog.info(val);
+
+ assertThat(val, StringContains.containsString("\"tag\":[{\"system\":\"scheme\",\"code\":\"term\",\"display\":\"label\"}]"));
+ b = ourCtx.newJsonParser().parseResource(Bundle.class, val);
+ assertEquals(1, b.getMeta().getTag().size());
+ assertEquals("scheme", b.getMeta().getTag().get(0).getSystem());
+ assertEquals("term", b.getMeta().getTag().get(0).getCode());
+ assertEquals("label", b.getMeta().getTag().get(0).getDisplay());
+
+ assertNotNull(b.getEntry().get(0).getResource());
+ Patient p = (Patient) b.getEntry().get(0).getResource();
+ assertEquals("idsystem", p.getIdentifier().get(0).getSystem());
+
+ }
+
+
+ @Test
+ public void testEncodeBundleEntryCategory() {
+
+ Bundle b = new Bundle();
+ BundleEntryComponent e = b.addEntry();
+ e.setResource(new Patient());
+ e.getResource().getMeta().addTag().setSystem("scheme").setCode( "term").setDisplay( "label");
+
+ String val = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(b);
+ ourLog.info(val);
+
+ assertThat(val, StringContains.containsString("{\"resourceType\":\"Bundle\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"meta\":{\"tag\":[{\"system\":\"scheme\",\"code\":\"term\",\"display\":\"label\"}]}}}]}"));
+
+ b = ourCtx.newJsonParser().parseResource(Bundle.class, val);
+ assertEquals(1, b.getEntry().size());
+ assertEquals(1, b.getEntry().get(0).getResource().getMeta().getTag().size());
+ assertEquals("scheme", b.getEntry().get(0).getResource().getMeta().getTag().get(0).getSystem());
+ assertEquals("term", b.getEntry().get(0).getResource().getMeta().getTag().get(0).getCode());
+ assertEquals("label", b.getEntry().get(0).getResource().getMeta().getTag().get(0).getDisplay());
+
+ }
+
+
+ @Test
+ public void testEncodeContained() {
+ IParser jsonParser = ourCtx.newJsonParser().setPrettyPrint(true);
+
+ // Create an organization, note that the organization does not have an ID
+ Organization org = new Organization();
+ org.getNameElement().setValue("Contained Test Organization");
+
+ // Create a patient
+ Patient patient = new Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
+
+ // Put the organization as a reference in the patient resource
+ patient.getManagingOrganization().setResource(org);
+
+ String encoded = jsonParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\": [", "\"id\": \"1\"", "\"identifier\"", "\"reference\": \"#1\"")));
+
+ // Create a bundle with just the patient resource
+ Bundle b = new Bundle();
+ b.addEntry().setResource(patient);
+
+ // Encode the bundle
+ encoded = jsonParser.encodeResourceToString(b);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\": [", "\"id\": \"1\"", "\"identifier\"", "\"reference\": \"#1\"")));
+
+ // Re-parse the bundle
+ patient = (Patient) jsonParser.parseResource(jsonParser.encodeResourceToString(patient));
+ assertEquals("#1", patient.getManagingOrganization().getReference());
+
+ assertNotNull(patient.getManagingOrganization().getResource());
+ org = (Organization) patient.getManagingOrganization().getResource();
+ assertEquals("#1", org.getIdElement().getValue());
+ assertEquals("Contained Test Organization", org.getName());
+
+ // And re-encode a second time
+ encoded = jsonParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\": [", "\"id\": \"1\"", "\"identifier\"", "\"reference\": \"#1\"")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("\"contained\":", "[", "\"contained\":"))));
+
+ // And re-encode once more, with the references cleared
+ patient.getContained().clear();
+ patient.getManagingOrganization().setReference(null);
+ encoded = jsonParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\": [", "\"id\": \"1\"", "\"identifier\"", "\"reference\": \"#1\"")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("\"contained\":", "[", "\"contained\":"))));
+
+ // And re-encode once more, with the references cleared and a manually set local ID
+ patient.getContained().clear();
+ patient.getManagingOrganization().setReference(null);
+ patient.getManagingOrganization().getResource().setId(("#333"));
+ encoded = jsonParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\": [", "\"id\": \"333\"", "\"identifier\"", "\"reference\": \"#333\"")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("\"contained\":", "[", "\"contained\":"))));
+
+ }
+
+ @Test
+ public void testEncodeContained__() {
+ // Create an organization
+ Organization org = new Organization();
+ org.getNameElement().setValue("Contained Test Organization");
+
+ // Create a patient
+ Patient patient = new Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue( "253345");
+ patient.getManagingOrganization().setResource(org);
+
+ // Create a bundle with just the patient resource
+ Bundle b = new Bundle();
+ b.addEntry().setResource(patient);
+
+ // Encode the buntdle
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\"", "resourceType\": \"Organization", "id\": \"1\"")));
+ assertThat(encoded, containsString("reference\": \"#1\""));
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("\"contained\"", "resourceType\": \"Organization", "id\": \"1\"")));
+ assertThat(encoded, containsString("reference\": \"#1\""));
+ }
+
+ @Test
+ public void testEncodeContainedResourcesMore() throws Exception {
+
+ DiagnosticReport rpt = new DiagnosticReport();
+ Specimen spm = new Specimen();
+ rpt.getText().setDivAsString("AAA");
+ rpt.addSpecimen().setResource(spm);
+
+ IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
+ String str = p.encodeResourceToString(rpt);
+
+ ourLog.info(str);
+ assertThat(str, StringContains.containsString("AAA
"));
+ String substring = "\"reference\": \"#";
+ assertThat(str, StringContains.containsString(substring));
+
+ int idx = str.indexOf(substring) + substring.length();
+ int idx2 = str.indexOf('"', idx + 1);
+ String id = str.substring(idx, idx2);
+ assertThat(str, StringContains.containsString("\"id\": \"" + id + "\""));
+ assertThat(str, IsNot.not(StringContains.containsString("")));
+
+ }
+
+ @Test
+ public void testEncodeContainedWithNarrativeIsSuppresed() throws Exception {
+ IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
+
+ // Create an organization, note that the organization does not have an ID
+ Organization org = new Organization();
+ org.getNameElement().setValue("Contained Test Organization");
+ org.getText().setDivAsString("FOOBAR
");
+
+ // Create a patient
+ Patient patient = new Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue( "253345");
+ patient.getText().setDivAsString("BARFOO
");
+ patient.getManagingOrganization().setResource(org);
+
+ String encoded = parser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, not(containsString("FOOBAR")));
+ assertThat(encoded, (containsString("BARFOO")));
+
+ }
+
+
+
+ @Test
+ public void testEncodeDeclaredExtensionWithAddressContent() {
+ IParser parser = ourCtx.newJsonParser();
+
+ MyPatientWithOneDeclaredAddressExtension patient = new MyPatientWithOneDeclaredAddressExtension();
+ patient.addAddress().setUse(AddressUse.HOME);
+ patient.setFoo(new Address().addLine("line1"));
+
+ String val = parser.encodeResourceToString(patient);
+ ourLog.info(val);
+ assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueAddress\":{\"line\":[\"line1\"]}}]"));
+
+ MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val);
+ assertEquals(AddressUse.HOME, patient.getAddress().get(0).getUse());
+ Address ref = actual.getFoo();
+ assertEquals("line1", ref.getLine().get(0).getValue());
+
+ }
+
+ @Test
+ public void testEncodeDeclaredExtensionWithResourceContent() {
+ IParser parser = ourCtx.newJsonParser();
+
+ MyPatientWithOneDeclaredExtension patient = new MyPatientWithOneDeclaredExtension();
+ patient.addAddress().setUse(AddressUse.HOME);
+ patient.setFoo(new Reference("Organization/123"));
+
+ String val = parser.encodeResourceToString(patient);
+ ourLog.info(val);
+ assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueReference\":{\"reference\":\"Organization/123\"}}]"));
+
+ MyPatientWithOneDeclaredExtension actual = parser.parseResource(MyPatientWithOneDeclaredExtension.class, val);
+ assertEquals(AddressUse.HOME, patient.getAddress().get(0).getUse());
+ Reference ref = actual.getFoo();
+ assertEquals("Organization/123", ref.getReference());
+
+ }
+
+ @Test
+ public void testEncodeExt() throws Exception {
+
+ ValueSet valueSet = new ValueSet();
+ valueSet.setId("123456");
+
+ ValueSetCodeSystemComponent define = valueSet.getCodeSystem();
+ ConceptDefinitionComponent code = define.addConcept();
+ code.setCode("someCode");
+ code.setDisplay("someDisplay");
+ code.addExtension().setUrl("urn:alt").setValue( new StringType("alt name"));
+
+
+ String encoded = ourCtx.newJsonParser().encodeResourceToString(valueSet);
+ ourLog.info(encoded);
+
+ assertThat(encoded, (containsString("123456")));
+ assertEquals(
+ "{\"resourceType\":\"ValueSet\",\"id\":\"123456\",\"codeSystem\":{\"concept\":[{\"extension\":[{\"url\":\"urn:alt\",\"valueString\":\"alt name\"}],\"code\":\"someCode\",\"display\":\"someDisplay\"}]}}",
+ encoded);
+
+ }
+
+ @Test
+ public void testEncodeExtensionInCompositeElement() {
+
+ Conformance c = new Conformance();
+ c.addRest().getSecurity().addExtension().setUrl("http://foo").setValue(new StringType("AAA"));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(c);
+ ourLog.info(encoded);
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(c);
+ ourLog.info(encoded);
+ assertEquals(encoded, "{\"resourceType\":\"Conformance\",\"rest\":[{\"security\":{\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"AAA\"}]}}]}");
+
+ }
+
+
+
+ @Test
+ public void testEncodeExtensionInPrimitiveElement() {
+
+ Conformance c = new Conformance();
+ c.getAcceptUnknownElement().addExtension().setUrl( "http://foo").setValue( new StringType("AAA"));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(c);
+ ourLog.info(encoded);
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(c);
+ ourLog.info(encoded);
+ assertEquals(encoded, "{\"resourceType\":\"Conformance\",\"_acceptUnknown\":{\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"AAA\"}]}}");
+
+ // Now with a value
+ ourLog.info("---------------");
+
+ c = new Conformance();
+ c.getAcceptUnknownElement().setValue(UnknownContentCode.EXTENSIONS);
+ c.getAcceptUnknownElement().addExtension().setUrl("http://foo").setValue( new StringType("AAA"));
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(c);
+ ourLog.info(encoded);
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(c);
+ ourLog.info(encoded);
+ assertEquals(encoded, "{\"resourceType\":\"Conformance\",\"acceptUnknown\":\"extensions\",\"_acceptUnknown\":{\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"AAA\"}]}}");
+
+ }
+
+ @Test
+ public void testEncodeExtensionInResourceElement() {
+
+ Conformance c = new Conformance();
+ // c.addRest().getSecurity().addUndeclaredExtension(false, "http://foo", new StringType("AAA"));
+ c.addExtension().setUrl("http://foo").setValue( new StringType("AAA"));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(c);
+ ourLog.info(encoded);
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(c);
+ ourLog.info(encoded);
+ assertEquals(encoded, "{\"resourceType\":\"Conformance\",\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"AAA\"}]}");
+
+ }
+
+ @Test
+ public void testEncodeExtensionOnEmptyElement() throws Exception {
+
+ ValueSet valueSet = new ValueSet();
+ valueSet.addUseContext().addExtension().setUrl("http://foo").setValue( new StringType("AAA"));
+
+ String encoded = ourCtx.newJsonParser().encodeResourceToString(valueSet);
+ assertThat(encoded, containsString("\"useContext\":[{\"extension\":[{\"url\":\"http://foo\",\"valueString\":\"AAA\"}]}"));
+
+ }
+
+
+ @Test
+ public void testEncodeExtensionWithResourceContent() {
+ IParser parser = ourCtx.newJsonParser();
+
+ Patient patient = new Patient();
+ patient.addAddress().setUse(AddressUse.HOME);
+ patient.addExtension().setUrl("urn:foo").setValue( new Reference("Organization/123"));
+
+ String val = parser.encodeResourceToString(patient);
+ ourLog.info(val);
+ assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueReference\":{\"reference\":\"Organization/123\"}}]"));
+
+ Patient actual = parser.parseResource(Patient.class, val);
+ assertEquals(AddressUse.HOME, patient.getAddress().get(0).getUse());
+ List ext = actual.getExtension();
+ assertEquals(1, ext.size());
+ Reference ref = (Reference) ext.get(0).getValue();
+ assertEquals("Organization/123", ref.getReference());
+
+ }
+
+ @Test
+ public void testEncodeIds() {
+ Patient pt = new Patient();
+ pt.addIdentifier().setSystem("sys").setValue( "val");
+
+ List_ list = new List_();
+ list.setId("listId");
+ list.addEntry().setItem(new Reference(pt)).setDeleted(true);
+
+ String enc = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(list);
+ ourLog.info(enc);
+
+ assertThat(enc, containsString("\"id\": \"1\""));
+
+ List_ parsed = ourCtx.newJsonParser().parseResource(List_.class,enc);
+ assertEquals(Patient.class, parsed.getEntry().get(0).getItem().getResource().getClass());
+ }
+
+ @Test
+ public void testEncodeInvalidChildGoodException() {
+ Observation obs = new Observation();
+ obs.setValue(new DecimalType(112.22));
+
+ IParser p = ourCtx.newJsonParser();
+
+ try {
+ p.encodeResourceToString(obs);
+ } catch (DataFormatException e) {
+ assertThat(e.getMessage(), StringContains.containsString("DecimalType"));
+ }
+ }
+
+ @Test
+ public void testEncodeNarrativeBlockInBundle() throws Exception {
+ Patient p = new Patient();
+ p.addIdentifier().setSystem("foo").setValue("bar");
+ p.getText().setStatus(NarrativeStatus.GENERATED);
+ p.getText().setDivAsString("AAA
");
+
+ Bundle b = new Bundle();
+ b.setTotal(123);
+ b.addEntry().setResource(p);
+
+ String str = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b);
+ ourLog.info(str);
+ assertThat(str, StringContains.containsString("AAA
"));
+
+ p.getText().setDivAsString("hello ");
+ str = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b);
+ ourLog.info(str);
+ // Backslashes need to be escaped because they are in a JSON value
+ assertThat(str, containsString(">hello<"));
+
+ }
+
+ @Test
+ public void testEncodeNonContained() {
+ Organization org = new Organization();
+ org.setId("Organization/65546");
+ org.getNameElement().setValue("Contained Test Organization");
+
+ Patient patient = new Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
+ patient.getManagingOrganization().setResource(org);
+
+ Bundle b = new Bundle();
+ b.addEntry().setResource(patient);
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(b);
+ ourLog.info(encoded);
+ assertThat(encoded, not(containsString("contained")));
+ assertThat(encoded, containsString("\"reference\": \"Organization/65546\""));
+
+ encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, not(containsString("contained")));
+ assertThat(encoded, containsString("\"reference\": \"Organization/65546\""));
+ }
+
+
+
+
+ @Test
+ public void testEncodeResourceRef() throws DataFormatException {
+
+ Patient patient = new Patient();
+ patient.setManagingOrganization(new Reference());
+
+ IParser p = ourCtx.newJsonParser();
+ String str = p.encodeResourceToString(patient);
+ assertThat(str, IsNot.not(StringContains.containsString("managingOrganization")));
+
+ patient.setManagingOrganization(new Reference("Organization/123"));
+ str = p.encodeResourceToString(patient);
+ assertThat(str, StringContains.containsString("\"managingOrganization\":{\"reference\":\"Organization/123\"}"));
+
+ Organization org = new Organization();
+ org.addIdentifier().setSystem("foo").setValue("bar");
+ patient.setManagingOrganization(new Reference(org));
+ str = p.encodeResourceToString(patient);
+ assertThat(str, StringContains.containsString("\"contained\":[{\"resourceType\":\"Organization\""));
+
+ }
+
+ @Test
+ public void testEncodeSummary() throws Exception {
+ Patient patient = new Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.setMaritalStatus(new CodeableConcept().setText("D"));
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).setSummaryMode(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("Patient"));
+ assertThat(encoded, stringContainsInOrder("\"tag\"",
+ "\"system\": \"" + Constants.TAG_SUBSETTED_SYSTEM + "\",", "\"code\": \"" + Constants.TAG_SUBSETTED_CODE+"\","));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, not(containsString("maritalStatus")));
+ }
+
+ @Test
+ public void testEncodeSummary2() throws Exception {
+ Patient patient = new Patient();
+ patient.setId("Patient/1/_history/1");
+ patient.getText().setDivAsString("THE DIV
");
+ patient.addName().addFamily("FAMILY");
+ patient.setMaritalStatus(new CodeableConcept().setText("D"));
+
+ patient.getMeta().addTag().setSystem("foo").setCode("bar");
+
+ String encoded = ourCtx.newJsonParser().setPrettyPrint(true).setSummaryMode(true).encodeResourceToString(patient);
+ ourLog.info(encoded);
+
+ assertThat(encoded, containsString("Patient"));
+ assertThat(encoded, stringContainsInOrder("\"tag\"",
+ "\"system\": \"foo\",", "\"code\": \"bar\"",
+ "\"system\": \"" + Constants.TAG_SUBSETTED_SYSTEM + "\",", "\"code\": \"" + Constants.TAG_SUBSETTED_CODE+"\","));
+ assertThat(encoded, not(containsString("THE DIV")));
+ assertThat(encoded, containsString("family"));
+ assertThat(encoded, not(containsString("maritalStatus")));
+ }
+
+ @Test
+ public void testEncodeUndeclaredExtensionWithAddressContent() {
+ IParser parser = ourCtx.newJsonParser();
+
+ Patient patient = new Patient();
+ patient.addAddress().setUse(AddressUse.HOME);
+ patient.addExtension().setUrl("urn:foo").setValue(new Address().addLine("line1"));
+
+ String val = parser.encodeResourceToString(patient);
+ ourLog.info(val);
+ assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueAddress\":{\"line\":[\"line1\"]}}]"));
+
+ MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val);
+ assertEquals(AddressUse.HOME, patient.getAddress().get(0).getUse());
+ Address ref = actual.getFoo();
+ assertEquals("line1", ref.getLine().get(0).getValue());
+
+ }
+
+ @Test
+ public void testEncodingNullExtension() {
+ Patient p = new Patient();
+ Extension extension = new Extension().setUrl("http://foo#bar");
+ p.getExtension().add(extension);
+ String str = ourCtx.newJsonParser().encodeResourceToString(p);
+
+ assertEquals("{\"resourceType\":\"Patient\"}", str);
+
+ extension.setValue(new StringType());
+
+ str = ourCtx.newJsonParser().encodeResourceToString(p);
+ assertEquals("{\"resourceType\":\"Patient\"}", str);
+
+ extension.setValue(new StringType(""));
+
+ str = ourCtx.newJsonParser().encodeResourceToString(p);
+ assertEquals("{\"resourceType\":\"Patient\"}", str);
+
+ }
+
+ @Test
+ public void testExtensionOnComposite() throws Exception {
+
+ Patient patient = new Patient();
+
+ HumanName name = patient.addName();
+ name.addFamily("Shmoe");
+ HumanName given = name.addGiven("Joe");
+ Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue( new StringType("Hello"));
+ given.getExtension().add(ext2);
+ String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
+ ourLog.info(enc);
+ assertEquals("{\"resourceType\":\"Patient\",\"name\":[{\"extension\":[{\"url\":\"http://examples.com#givenext\",\"valueString\":\"Hello\"}],\"family\":[\"Shmoe\"],\"given\":[\"Joe\"]}]}", enc);
+
+ IParser newJsonParser = ourCtx.newJsonParser();
+ StringReader reader = new StringReader(enc);
+ Patient parsed = newJsonParser.parseResource(Patient.class, reader);
+
+ ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(parsed));
+
+ assertEquals(1, parsed.getName().get(0).getExtension().size());
+ Extension ext = parsed.getName().get(0).getExtension().get(0);
+ assertEquals("Hello", ((IPrimitiveType>)ext.getValue()).getValue());
+
+ }
+
+ @Test
+ public void testExtensionOnPrimitive() throws Exception {
+
+ Patient patient = new Patient();
+
+ HumanName name = patient.addName();
+ StringType family = name.addFamilyElement();
+ family.setValue("Shmoe");
+
+ family.addExtension().setUrl("http://examples.com#givenext").setValue( new StringType("Hello"));
+ String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
+ ourLog.info(enc);
+ //@formatter:off
+ assertThat(enc, containsString(("{\n" +
+ " \"resourceType\":\"Patient\",\n" +
+ " \"name\":[\n" +
+ " {\n" +
+ " \"family\":[\n" +
+ " \"Shmoe\"\n" +
+ " ],\n" +
+ " \"_family\":[\n" +
+ " {\n" +
+ " \"extension\":[\n" +
+ " {\n" +
+ " \"url\":\"http://examples.com#givenext\",\n" +
+ " \"valueString\":\"Hello\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ "}").replace("\n", "").replaceAll(" +", "")));
+ //@formatter:on
+
+ Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, new StringReader(enc));
+ assertEquals(1, parsed.getName().get(0).getFamily().get(0).getExtension().size());
+ Extension ext = parsed.getName().get(0).getFamily().get(0).getExtension().get(0);
+ assertEquals("Hello", ((IPrimitiveType>) ext.getValue()).getValue());
+
+ }
+
+ @Test
+ public void testMoreExtensions() throws Exception {
+
+ Patient patient = new Patient();
+ patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
+
+ Extension ext = new Extension();
+ ext.setUrl("http://example.com/extensions#someext");
+ ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
+
+ // Add the extension to the resource
+ patient.getExtension().add(ext);
+ // END SNIPPET: resourceExtension
+
+ // START SNIPPET: resourceStringExtension
+ HumanName name = patient.addName();
+ name.addFamily("Shmoe");
+ StringType given = name.addGivenElement();
+ given.setValue("Joe");
+ Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given"));
+ given.getExtension().add(ext2);
+
+ StringType given2 = name.addGivenElement();
+ given2.setValue("Shmoe");
+ Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent");
+ given2.getExtension().add(given2ext);
+ given2ext.addExtension().setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD"));
+ // END SNIPPET: resourceStringExtension
+
+ // START SNIPPET: subExtension
+ Extension parent = new Extension().setUrl("http://example.com#parent");
+ patient.getExtension().add(parent);
+
+ Extension child1 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
+ parent.getExtension().add(child1);
+
+ Extension child2 = new Extension().setUrl("http://example.com#child").setValue(new StringType("value1"));
+ parent.getExtension().add(child2);
+ // END SNIPPET: subExtension
+
+ String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(output);
+
+ String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
+ //@formatter:off
+ assertThat(enc, containsString(("{" +
+ "\"resourceType\":\"Patient\"," +
+ " \"extension\":[" +
+ " {" +
+ " \"url\":\"http://example.com/extensions#someext\"," +
+ " \"valueDateTime\":\"2011-01-02T11:13:15\"" +
+ " }," +
+ " {" +
+ " \"url\":\"http://example.com#parent\"," +
+ " \"extension\":[" +
+ " {" +
+ " \"url\":\"http://example.com#child\"," +
+ " \"valueString\":\"value1\"" +
+ " }," +
+ " {" +
+ " \"url\":\"http://example.com#child\"," +
+ " \"valueString\":\"value1\"" +
+ " }" +
+ " ]" +
+ " }" +
+ " ]").replace(" ", "")));
+ //@formatter:on
+
+ //@formatter:off
+ assertThat(enc, containsString((
+ " \"given\":[" +
+ " \"Joe\"," +
+ " \"Shmoe\"" +
+ " ]," +
+ " \"_given\":[" +
+ " {" +
+ " \"extension\":[" +
+ " {" +
+ " \"url\":\"http://examples.com#givenext\"," +
+ " \"valueString\":\"given\"" +
+ " }" +
+ " ]" +
+ " }," +
+ " {" +
+ " \"extension\":[" +
+ " {" +
+ " \"url\":\"http://examples.com#givenext_parent\"," +
+ " \"extension\":[" +
+ " {" +
+ " \"url\":\"http://examples.com#givenext_child\"," +
+ " \"valueString\":\"CHILD\"" +
+ " }" +
+ " ]" +
+ " }" +
+ " ]" +
+ " }" +
+ "").replace(" ", "")));
+ //@formatter:on
+ }
+
+ @Test
+ public void testNestedContainedResources() {
+
+ Observation A = new Observation();
+ A.getCode().setText("A");
+
+ Observation B = new Observation();
+ B.getCode().setText("B");
+ A.addRelated().setTarget(new Reference(B));
+
+ Observation C = new Observation();
+ C.getCode().setText("C");
+ B.addRelated().setTarget(new Reference(C));
+
+ String str = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(A);
+ ourLog.info(str);
+
+ assertThat(str, stringContainsInOrder(Arrays.asList("\"text\": \"B\"", "\"text\": \"C\"", "\"text\": \"A\"")));
+
+ // Only one (outer) contained block
+ int idx0 = str.indexOf("\"contained\"");
+ int idx1 = str.indexOf("\"contained\"", idx0 + 1);
+
+ assertNotEquals(-1, idx0);
+ assertEquals(-1, idx1);
+
+ Observation obs = ourCtx.newJsonParser().parseResource(Observation.class, str);
+ assertEquals("A", obs.getCode().getTextElement().getValue());
+
+ Observation obsB = (Observation) obs.getRelated().get(0).getTarget().getResource();
+ assertEquals("B", obsB.getCode().getTextElement().getValue());
+
+ Observation obsC = (Observation) obsB.getRelated().get(0).getTarget().getResource();
+ assertEquals("C", obsC.getCode().getTextElement().getValue());
+
+ }
+
+ @Test
+ public void testParseBinaryResource() {
+
+ Binary val = ourCtx.newJsonParser().parseResource(Binary.class, "{\"resourceType\":\"Binary\",\"contentType\":\"foo\",\"content\":\"AQIDBA==\"}");
+ assertEquals("foo", val.getContentType());
+ assertArrayEquals(new byte[] { 1, 2, 3, 4 }, val.getContent());
+
+ }
+
+ @Test
+ public void testParseEmptyNarrative() throws Exception {
+ //@formatter:off
+ String text = "{\n" +
+ " \"resourceType\" : \"Patient\",\n" +
+ " \"extension\" : [\n" +
+ " {\n" +
+ " \"url\" : \"http://clairol.org/colour\",\n" +
+ " \"valueCode\" : \"B\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"text\" : {\n" +
+ " \"div\" : \"\"\n" +
+ " }" +
+ "}";
+ //@formatter:on
+
+ Patient res = (Patient) ourCtx.newJsonParser().parseResource(text);
+ XhtmlNode div = res.getText().getDiv();
+ String value = div.getValueAsString();
+
+ assertNull(value);
+ List childNodes = div.getChildNodes();
+ assertTrue(childNodes == null || childNodes.isEmpty());
+ }
+
+ @Test
+ public void testParseSimpleBundle() {
+ String bundle = "{\"resourceType\":\"Bundle\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"identifier\":[{\"system\":\"idsystem\"}]}}]}";
+ Bundle b = ourCtx.newJsonParser().parseResource(Bundle.class, bundle);
+
+ assertNotNull(b.getEntry().get(0).getResource());
+ Patient p = (Patient) b.getEntry().get(0).getResource();
+ assertEquals("idsystem", p.getIdentifier().get(0).getSystem());
+ }
+
+ @Test
+ public void testParseSingleQuotes() {
+ ourCtx.newJsonParser().parseResource(Bundle.class, "{ \"resourceType\": \"Bundle\" }");
+ ourCtx.newJsonParser().parseResource(Bundle.class, "{ 'resourceType': 'Bundle' }");
+ }
+
+ @Test
+ public void testSimpleParse() throws DataFormatException, IOException {
+
+ String msg = IOUtils.toString(JsonParserHl7OrgDstu2Test.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.json"));
+ IParser p = ourCtx.newJsonParser();
+ // ourLog.info("Reading in message: {}", msg);
+ Patient res = p.parseResource(Patient.class, msg);
+
+ assertEquals(2, res.getExtension().size());
+ assertEquals(1, res.getModifierExtension().size());
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res);
+ ourLog.info(encoded);
+
+ }
+
+ @Test
+ public void testParsePrimitiveExtension() {
+ //@formatter:off
+ String input = "{\n" +
+ " \"resourceType\":\"Patient\",\n" +
+ " \"contact\":[\n" +
+ " {\n" +
+ " \"name\":{\n" +
+ " \"family\":[\n" +
+ " \"du\",\n" +
+ " \"Marché\"\n" +
+ " ],\n" +
+ " \"_family\":[\n" +
+ " {\n" +
+ " \"extension\":[\n" +
+ " {\n" +
+ " \"url\":\"http://hl7.org/fhir/Profile/iso-21090#qualifier\",\n" +
+ " \"valueCode\":\"VV\"\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " null\n" +
+ " ]\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+ //@formatter:off
+
+ Patient p = ourCtx.newJsonParser().parseResource(Patient.class, input);
+ ContactComponent contact = p.getContact().get(0);
+ StringType family = contact.getName().getFamily().get(0);
+
+ assertEquals("du", family.getValueAsString());
+ assertEquals(1, family.getExtension().size());
+ }
+
+
+ @Test
+ public void testSimpleResourceEncodeWithCustomType() throws IOException, SAXException {
+
+ String jsonString = IOUtils.toString(JsonParserHl7OrgDstu2Test.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.json"), Charset.forName("UTF-8"));
+ MyObservationWithExtensions obs = ourCtx.newJsonParser().parseResource(MyObservationWithExtensions.class, jsonString);
+
+ {
+ ContactComponent contact = obs.getContact().get(0);
+ StringType family = contact.getName().getFamily().get(0);
+ assertEquals("du", family.getValueAsString());
+ assertEquals(1, family.getExtension().size());
+ }
+
+ assertEquals(0, obs.getExtension().size());
+ assertEquals("aaaa", obs.getExtAtt().getContentType());
+ assertEquals("str1", obs.getMoreExt().getStr1().getValue());
+ assertEquals("2011-01-02", obs.getModExt().getValueAsString());
+
+ List undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getExtension();
+ Extension undeclaredExtension = undeclaredExtensions.get(0);
+ assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl());
+
+ IParser xmlParser = ourCtx.newXmlParser();
+ String encoded = xmlParser.encodeResourceToString(obs);
+ encoded = encoded.replaceAll("", "").replace("\n", "").replace("\r", "").replaceAll(">\\s+<", "><");
+
+ String xmlString = IOUtils.toString(JsonParserHl7OrgDstu2Test.class.getResourceAsStream("/example-patient-general-hl7orgdstu2.xml"), Charset.forName("UTF-8"));
+ xmlString = xmlString.replaceAll("", "").replace("\n", "").replace("\r", "").replaceAll(">\\s+<", "><");
+
+ ourLog.info("Expected: " + xmlString);
+ ourLog.info("Actual : " + encoded);
+
+ String expected = (xmlString);
+ String actual = (encoded.trim());
+
+ XmlParserHl7OrgDstu2Test.compareXml(expected, actual);
+ }
+
+
+ @Test
+ public void testBaseUrlFooResourceCorrectlySerializedInExtensionValueReference() {
+ String refVal = "http://my.org/FooBar";
+
+ Patient fhirPat = new Patient();
+ fhirPat.addExtension().setUrl("x1").setValue(new Reference(refVal));
+
+ IParser parser = ourCtx.newJsonParser();
+
+ String output = parser.encodeResourceToString(fhirPat);
+ System.out.println("output: " + output);
+
+ // Deserialize then check that valueReference value is still correct
+ fhirPat = parser.parseResource(Patient.class, output);
+
+ List extlst = fhirPat.getExtension();
+ Assert.assertEquals(1, extlst.size());
+ Assert.assertEquals(refVal, ((Reference) extlst.get(0).getValue()).getReference());
+ }
+
+ @ResourceDef(name = "Patient")
+ public static class MyPatientWithOneDeclaredAddressExtension extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(order = 0, name = "foo")
+ @ca.uhn.fhir.model.api.annotation.Extension(url = "urn:foo", definedLocally = true, isModifier = false)
+ private Address myFoo;
+
+ public Address getFoo() {
+ return myFoo;
+ }
+
+ public void setFoo(Address theFoo) {
+ myFoo = theFoo;
+ }
+
+ }
+
+ @ResourceDef(name = "Patient")
+ public static class MyPatientWithOneDeclaredExtension extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(order = 0, name = "foo")
+ @ca.uhn.fhir.model.api.annotation.Extension(url = "urn:foo", definedLocally = true, isModifier = false)
+ private Reference myFoo;
+
+ public Reference getFoo() {
+ return myFoo;
+ }
+
+ public void setFoo(Reference theFoo) {
+ myFoo = theFoo;
+ }
+
+ }
+
+ private Matcher super String> stringContainsInOrder(java.lang.String... substrings) {
+ return Matchers.stringContainsInOrder(Arrays.asList(substrings));
+ }
+
+ private Matcher super String> stringContainsInOrder(List substrings) {
+ return Matchers.stringContainsInOrder(substrings);
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyObservationWithExtensions.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyObservationWithExtensions.java
new file mode 100644
index 00000000000..f9b030253d9
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyObservationWithExtensions.java
@@ -0,0 +1,106 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import ca.uhn.fhir.model.api.annotation.Block;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.Extension;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.util.ElementUtil;
+import org.hl7.fhir.instance.model.Attachment;
+import org.hl7.fhir.instance.model.BackboneElement;
+import org.hl7.fhir.instance.model.DateType;
+import org.hl7.fhir.instance.model.Patient;
+import org.hl7.fhir.instance.model.StringType;
+import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
+
+
+@ResourceDef(name="Patient")
+public class MyObservationWithExtensions extends Patient {
+
+ @Extension(url = "urn:patientext:att", definedLocally = false, isModifier = false)
+ @Child(name = "extAtt", order = 0)
+ private Attachment myExtAtt;
+
+ @Extension(url = "urn:patientext:moreext", definedLocally = false, isModifier = false)
+ @Child(name = "moreExt", order = 1)
+ private MoreExt myMoreExt;
+
+ @Extension(url = "urn:modext", definedLocally = false, isModifier = true)
+ @Child(name = "modExt", order = 2)
+ private DateType myModExt;
+
+ public Attachment getExtAtt() {
+ return myExtAtt;
+ }
+
+ public MoreExt getMoreExt() {
+ return myMoreExt;
+ }
+
+ public void setMoreExt(MoreExt theMoreExt) {
+ myMoreExt = theMoreExt;
+ }
+
+ public DateType getModExt() {
+ return myModExt;
+ }
+
+ public void setModExt(DateType theModExt) {
+ myModExt = theModExt;
+ }
+
+ public void setExtAtt(Attachment theExtAtt) {
+ myExtAtt = theExtAtt;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty() && ElementUtil.isEmpty(myExtAtt, myModExt, myMoreExt);
+ }
+
+ /**
+ * Block class for child element: Observation.referenceRange (Provides guide for interpretation)
+ *
+ *
+ * Definition: Guidance on how to interpret the value by comparison to a normal or recommended range
+ *
+ */
+ @Block(name = "Observation.someExtensions")
+ public static class MoreExt extends BackboneElement implements IBaseBackboneElement {
+
+ @Extension(url = "urn:patientext:moreext:1", definedLocally = false, isModifier = false)
+ @Child(name = "str1", order = 0)
+ private StringType myStr1;
+
+ @Extension(url = "urn:patientext:moreext:2", definedLocally = false, isModifier = false)
+ @Child(name = "str2", order = 1)
+ private StringType myStr2;
+
+ public StringType getStr1() {
+ return myStr1;
+ }
+
+ public void setStr1(StringType theStr1) {
+ myStr1 = theStr1;
+ }
+
+ public StringType getStr2() {
+ return myStr2;
+ }
+
+ public void setStr2(StringType theStr2) {
+ myStr2 = theStr2;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return ElementUtil.isEmpty(myStr1, myStr2);
+ }
+
+ @Override
+ public BackboneElement copy() {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyOrganizationDstu2.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyOrganizationDstu2.java
new file mode 100644
index 00000000000..d0d6820a724
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyOrganizationDstu2.java
@@ -0,0 +1,11 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import org.hl7.fhir.instance.model.Organization;
+
+@ResourceDef()
+public class MyOrganizationDstu2 extends Organization {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyPatientHl7Org.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyPatientHl7Org.java
new file mode 100644
index 00000000000..c76e2bbf8fb
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyPatientHl7Org.java
@@ -0,0 +1,64 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import java.util.ArrayList;
+import java.util.List;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.Description;
+import ca.uhn.fhir.model.api.annotation.Extension;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import org.hl7.fhir.instance.model.DateTimeType;
+import org.hl7.fhir.instance.model.Patient;
+import org.hl7.fhir.instance.model.Reference;
+import org.hl7.fhir.instance.model.StringType;
+
+
+@ResourceDef()
+public class MyPatientHl7Org extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(name="petName")
+ @Extension(url="http://example.com/dontuse#petname", definedLocally=false, isModifier=false)
+ @Description(shortDefinition="The name of the patient's favourite pet")
+ private StringType myPetName;
+
+ @Child(name="importantDates", max=Child.MAX_UNLIMITED)
+ @Extension(url="http://example.com/dontuse#importantDates", definedLocally=false, isModifier=true)
+ @Description(shortDefinition="Some dates of note for the patient")
+ private List myImportantDates;
+
+ @Child(name="managingOrganization", order=Child.REPLACE_PARENT, min=0, max=1, type={
+ MyOrganizationDstu2.class })
+ @Description(
+ shortDefinition="Organization that is the custodian of the patient record",
+ formalDefinition="Organization that is the custodian of the patient record"
+ )
+ private Reference myManagingOrganization;
+
+
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty() && myPetName.isEmpty();
+ }
+
+
+ public List getImportantDates() {
+ if (myImportantDates==null) {
+ myImportantDates = new ArrayList();
+ }
+ return myImportantDates;
+ }
+
+ public StringType getPetName() {
+ return myPetName;
+ }
+
+ public void setImportantDates(List theImportantDates) {
+ myImportantDates = theImportantDates;
+ }
+
+ public void setPetName(StringType thePetName) {
+ myPetName = thePetName;
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyPatientWithOneDeclaredEnumerationExtension.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyPatientWithOneDeclaredEnumerationExtension.java
new file mode 100644
index 00000000000..2f62b1b27fe
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/MyPatientWithOneDeclaredEnumerationExtension.java
@@ -0,0 +1,26 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import org.hl7.fhir.instance.model.Address.AddressUse;
+import org.hl7.fhir.instance.model.Enumeration;
+import org.hl7.fhir.instance.model.Patient;
+
+@ResourceDef(name = "Patient")
+public class MyPatientWithOneDeclaredEnumerationExtension extends Patient {
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(order = 0, name = "foo")
+ @ca.uhn.fhir.model.api.annotation.Extension(url = "urn:foo", definedLocally = true, isModifier = false)
+ private Enumeration myFoo;
+
+ public Enumeration getFoo() {
+ return myFoo;
+ }
+
+ public void setFoo(Enumeration theFoo) {
+ myFoo = theFoo;
+ }
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/ResourceWithExtensionsA.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/ResourceWithExtensionsA.java
new file mode 100644
index 00000000000..5f8241084cf
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/ResourceWithExtensionsA.java
@@ -0,0 +1,206 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import java.util.List;
+import ca.uhn.fhir.model.api.annotation.Block;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.Description;
+import ca.uhn.fhir.model.api.annotation.Extension;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import org.hl7.fhir.instance.model.BackboneElement;
+import org.hl7.fhir.instance.model.CodeableConcept;
+import org.hl7.fhir.instance.model.DateType;
+import org.hl7.fhir.instance.model.DomainResource;
+import org.hl7.fhir.instance.model.Identifier;
+import org.hl7.fhir.instance.model.ResourceType;
+import org.hl7.fhir.instance.model.StringType;
+
+@ResourceDef(name = "ResourceWithExtensionsA", id="0001")
+public class ResourceWithExtensionsA extends DomainResource {
+
+ /*
+ * NB: several unit tests depend on the structure here
+ * so check the unit tests immediately after any changes
+ */
+
+
+ private static final long serialVersionUID = 1L;
+
+ @Child(name = "foo1", type = StringType.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
+ @Extension(url = "http://foo/#f1", definedLocally=true, isModifier=false)
+ private List myFoo1;
+
+ @Child(name = "foo2", type = StringType.class, order = 1, min = 0, max = 1)
+ @Extension(url = "http://foo/#f2", definedLocally=true, isModifier=true)
+ private StringType myFoo2;
+
+ @Child(name = "bar1", type = Bar1.class, order = 2, min = 1, max = Child.MAX_UNLIMITED)
+ @Extension(url = "http://bar/#b1", definedLocally=true, isModifier=false)
+ private List myBar1;
+
+ @Child(name = "bar2", type = Bar1.class, order = 3, min = 1, max = Child.MAX_UNLIMITED)
+ @Extension(url = "http://bar/#b2", definedLocally=true, isModifier=false)
+ private Bar1 myBar2;
+
+ @Child(name="baz", type = CodeableConcept.class, order = 4)
+ @Extension(url= "http://baz/#baz", definedLocally=true, isModifier=false)
+ @Description(shortDefinition = "Contains a codeable concept")
+ private CodeableConcept myBaz;
+
+ @Child(name = "identifier", type = Identifier.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
+ private List myIdentifier;
+
+ public List getBar1() {
+ return myBar1;
+ }
+
+ public Bar1 getBar2() {
+ return myBar2;
+ }
+
+ public List getFoo1() {
+ return myFoo1;
+ }
+
+ public StringType getFoo2() {
+ return myFoo2;
+ }
+
+ public CodeableConcept getBaz() { return myBaz; }
+
+ public List getIdentifier() {
+ return myIdentifier;
+ }
+
+ public void setBar1(List theBar1) {
+ myBar1 = theBar1;
+ }
+
+ public void setBar2(Bar1 theBar2) {
+ myBar2 = theBar2;
+ }
+
+ public void setFoo1(List theFoo1) {
+ myFoo1 = theFoo1;
+ }
+
+ public void setFoo2(StringType theFoo2) {
+ myFoo2 = theFoo2;
+ }
+
+ public void setBaz(CodeableConcept myBaz) { this.myBaz = myBaz; }
+
+ public void setIdentifier(List theValue) {
+ myIdentifier = theValue;
+ }
+
+ @Block(name = "Bar1")
+ public static class Bar1 extends BackboneElement {
+
+ public Bar1() {
+ super();
+ }
+
+ @Child(name = "bar11", type = DateType.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
+ @Extension(url = "http://bar/#b1/1", definedLocally=true, isModifier=false)
+ private List myBar11;
+
+ @Child(name = "bar12", type = DateType.class, order = 1, min = 0, max = Child.MAX_UNLIMITED)
+ @Extension(url = "http://bar/#b1/2", definedLocally=true, isModifier=false)
+ private List myBar12;
+
+ @Override
+ public boolean isEmpty() {
+ return false; // not implemented
+ }
+
+ public List getBar11() {
+ return myBar11;
+ }
+
+ public List getBar12() {
+ return myBar12;
+ }
+
+ public void setBar11(List theBar11) {
+ myBar11 = theBar11;
+ }
+
+ public void setBar12(List theBar12) {
+ myBar12 = theBar12;
+ }
+
+
+ @Override
+ public BackboneElement copy() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+ }
+
+ @Block(name = "Bar2")
+ public static class Bar2 extends BackboneElement {
+
+ @Child(name = "bar121", type = DateType.class, order = 0, min = 0, max = Child.MAX_UNLIMITED)
+ @Extension(url = "http://bar/#b1/2/1", definedLocally=true, isModifier=false)
+ private List myBar121;
+
+ @Child(name = "bar122", type = DateType.class, order = 1, min = 0, max = Child.MAX_UNLIMITED)
+ @Extension(url = "http://bar/#b1/2/2", definedLocally=true, isModifier=false)
+ private List myBar122;
+
+ @Override
+ public boolean isEmpty() {
+ return false; // not implemented
+ }
+
+
+ public List getBar121() {
+ return myBar121;
+ }
+
+ public List getBar122() {
+ return myBar122;
+ }
+
+ public void setBar121(List theBar121) {
+ myBar121 = theBar121;
+ }
+
+ public void setBar122(List theBar122) {
+ myBar122 = theBar122;
+ }
+
+ @Override
+ public BackboneElement copy() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false; // not implemented
+ }
+
+
+ @Override
+ public DomainResource copy() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ResourceType getResourceType() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+
+}
diff --git a/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/XmlParserHl7OrgDstu2Test.java b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/XmlParserHl7OrgDstu2Test.java
new file mode 100644
index 00000000000..ea8c81ed73b
--- /dev/null
+++ b/osgi/hapi-fhir-karaf-integration-tests/src/test/java/ca/uhn/fhir/tests/integration/karaf/dstu2hl7org/XmlParserHl7OrgDstu2Test.java
@@ -0,0 +1,1521 @@
+package ca.uhn.fhir.tests.integration.karaf.dstu2hl7org;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.context.api.AddProfileTagEnum;
+import ca.uhn.fhir.model.api.annotation.Child;
+import ca.uhn.fhir.model.api.annotation.ResourceDef;
+import ca.uhn.fhir.narrative.INarrativeGenerator;
+import ca.uhn.fhir.parser.DataFormatException;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.rest.api.Constants;
+import org.apache.commons.io.IOUtils;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.core.IsNot;
+import org.hamcrest.core.StringContains;
+import org.hamcrest.text.StringContainsInOrder;
+import org.hl7.fhir.instance.model.Address;
+import org.hl7.fhir.instance.model.CodeableConcept;
+import org.hl7.fhir.instance.model.Composition;
+import org.hl7.fhir.instance.model.DiagnosticReport;
+import org.hl7.fhir.instance.model.EnumFactory;
+import org.hl7.fhir.instance.model.Enumeration;
+import org.hl7.fhir.instance.model.InstantType;
+import org.hl7.fhir.instance.model.Narrative;
+import org.hl7.fhir.instance.model.Organization;
+import org.hl7.fhir.instance.model.Patient;
+import org.hl7.fhir.instance.model.PrimitiveType;
+import org.hl7.fhir.instance.model.Reference;
+import org.hl7.fhir.instance.model.Resource;
+import org.hl7.fhir.instance.model.Specimen;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.instance.model.api.INarrative;
+import org.hl7.fhir.instance.model.api.IPrimitiveType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.xml.sax.SAXException;
+import org.xmlunit.builder.DiffBuilder;
+import org.xmlunit.builder.Input;
+import org.xmlunit.diff.ComparisonControllers;
+import org.xmlunit.diff.DefaultNodeMatcher;
+import org.xmlunit.diff.Diff;
+import org.xmlunit.diff.ElementSelectors;
+
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.HAPI_FHIR_HL7ORG_DSTU2;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.KARAF;
+import static ca.uhn.fhir.tests.integration.karaf.PaxExamOptions.WRAP;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
+
+
+/**
+ * Useful docs about this test: https://ops4j1.jira.com/wiki/display/paxexam/FAQ
+ */
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class XmlParserHl7OrgDstu2Test {
+
+ private final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserHl7OrgDstu2Test.class);
+ private FhirContext ourCtx = FhirContext.forDstu2Hl7Org();
+
+ @Configuration
+ public Option[] config() throws IOException {
+ return options(
+ KARAF.option(),
+ WRAP.option(),
+ HAPI_FHIR_HL7ORG_DSTU2.option(),
+ mavenBundle().groupId("org.xmlunit").artifactId("xmlunit-core").versionAsInProject(),
+ mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.hamcrest").versionAsInProject(),
+ when(false)
+ .useOptions(
+ debugConfiguration("5005", true))
+ );
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlEnabled() {
+ String tmp = " ";
+ org.hl7.fhir.instance.model.Bundle bundle = (org.hl7.fhir.instance.model.Bundle) ourCtx.newXmlParser().parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ org.hl7.fhir.instance.model.Patient o1 = (org.hl7.fhir.instance.model.Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertEquals("http://lalaland.org", o1Id.getBaseUrl());
+ assertEquals("patient", o1Id.getResourceType());
+ assertEquals("pat1", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnFhirContext() {
+ String tmp = " ";
+ ourCtx.getParserOptions().setOverrideResourceIdWithBundleEntryFullUrl(false);
+ org.hl7.fhir.instance.model.Bundle bundle = (org.hl7.fhir.instance.model.Bundle) ourCtx.newXmlParser().parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ org.hl7.fhir.instance.model.Patient o1 = (org.hl7.fhir.instance.model.Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ }
+
+ @Test
+ public void testOverrideResourceIdWithBundleEntryFullUrlDisabled_ConfiguredOnParser() {
+ String tmp = " ";
+ org.hl7.fhir.instance.model.Bundle bundle = (org.hl7.fhir.instance.model.Bundle) ourCtx.newXmlParser().setOverrideResourceIdWithBundleEntryFullUrl(false).parseResource(tmp);
+ assertEquals(1, bundle.getEntry().size());
+ {
+ org.hl7.fhir.instance.model.Patient o1 = (org.hl7.fhir.instance.model.Patient) bundle.getEntry().get(0).getResource();
+ IIdType o1Id = o1.getIdElement();
+ assertFalse(o1Id.hasBaseUrl());
+ assertEquals("Patient", o1Id.getResourceType());
+ assertEquals("patxuzos", o1Id.getIdPart());
+ assertFalse(o1Id.hasVersionIdPart());
+ }
+ }
+
+ @Test
+ public void testComposition() {
+
+ Composition comp = new Composition();
+ comp.setId("1");
+
+ ourCtx.newXmlParser().encodeResourceToString(comp);
+ ourCtx.newXmlParser().encodeResourceToString(comp);
+ ourCtx.newXmlParser().encodeResourceToString(comp);
+ ourCtx.newXmlParser().encodeResourceToString(comp);
+
+ // comp.
+
+ }
+
+ @Test
+ public void testContainedResourceInExtensionUndeclared() {
+ org.hl7.fhir.instance.model.Patient p = new org.hl7.fhir.instance.model.Patient();
+ p.addName().addFamily("PATIENT");
+
+ Organization o = new Organization();
+ o.setName("ORG");
+ p.addExtension().setUrl("urn:foo").setValue(new org.hl7.fhir.instance.model.Reference(o));
+
+ String str = ourCtx.newXmlParser().encodeResourceToString(p);
+ ourLog.info(str);
+
+ p = ourCtx.newXmlParser().parseResource(org.hl7.fhir.instance.model.Patient.class, str);
+ assertEquals("PATIENT", p.getName().get(0).getFamily().get(0).getValue());
+
+ List exts = p.getExtension();
+ assertEquals(1, exts.size());
+ org.hl7.fhir.instance.model.Reference rr = (org.hl7.fhir.instance.model.Reference) exts.get(0).getValue();
+ o = (Organization) rr.getResource();
+ assertEquals("ORG", o.getName());
+ }
+
+ @Test
+ public void testDuplicateContainedResources() {
+
+ org.hl7.fhir.instance.model.Observation resA = new org.hl7.fhir.instance.model.Observation();
+ resA.getCode().setText("A");
+
+ org.hl7.fhir.instance.model.Observation resB = new org.hl7.fhir.instance.model.Observation();
+ resB.getCode().setText("B");
+ resB.addRelated().setTarget(new org.hl7.fhir.instance.model.Reference(resA));
+ resB.addRelated().setTarget(new org.hl7.fhir.instance.model.Reference(resA));
+
+ String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resB);
+ ourLog.info(encoded);
+
+ assertThat(encoded,
+ stringContainsInOrder(Arrays.asList("", "", " ")));
+ assertThat(encoded, not(stringContainsInOrder(
+ Arrays.asList("", "", ""))));
+
+ }
+
+ @Test
+ public void testEncodeAndParseContained() {
+ IParser xmlParser = ourCtx.newXmlParser().setPrettyPrint(true);
+
+ // Create an organization, note that the organization does not have an ID
+ Organization org = new Organization();
+ org.getNameElement().setValue("Contained Test Organization");
+
+ // Create a patient
+ org.hl7.fhir.instance.model.Patient patient = new org.hl7.fhir.instance.model.Patient();
+ patient.setId("Patient/1333");
+ patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
+
+ // Put the organization as a reference in the patient resource
+ patient.getManagingOrganization().setResource(org);
+
+ String encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, containsString(""));
+ assertThat(encoded, containsString(""));
+
+ // Create a bundle with just the patient resource
+ org.hl7.fhir.instance.model.Bundle b = new org.hl7.fhir.instance.model.Bundle();
+ b.addEntry().setResource(patient);
+
+ // Encode the bundle
+ encoded = xmlParser.encodeResourceToString(b);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "", " ")));
+ assertThat(encoded, containsString(""));
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", " ")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", " ", ""))));
+
+ // Re-parse the bundle
+ patient = (org.hl7.fhir.instance.model.Patient) xmlParser.parseResource(xmlParser.encodeResourceToString(patient));
+ assertEquals("#1", patient.getManagingOrganization().getReferenceElement().getValue());
+
+ assertNotNull(patient.getManagingOrganization().getResource());
+ org = (Organization) patient.getManagingOrganization().getResource();
+ assertEquals("#1", org.getIdElement().getValue());
+ assertEquals("Contained Test Organization", org.getName());
+
+ // And re-encode a second time
+ encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "",
+ " ", "")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", ""))));
+ assertThat(encoded, containsString(""));
+
+ // And re-encode once more, with the references cleared
+ patient.getContained().clear();
+ patient.getManagingOrganization().setReference(null);
+ encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "",
+ " ", "")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", ""))));
+ assertThat(encoded, containsString(""));
+
+ // And re-encode once more, with the references cleared and a manually set
+ // local ID
+ patient.getContained().clear();
+ patient.getManagingOrganization().setReference(null);
+ patient.getManagingOrganization().getResource().setId(("#333"));
+ encoded = xmlParser.encodeResourceToString(patient);
+ ourLog.info(encoded);
+ assertThat(encoded, stringContainsInOrder(Arrays.asList("", "",
+ " ", "")));
+ assertThat(encoded, not(stringContainsInOrder(Arrays.asList("", ""))));
+
+ }
+
+ @Test
+ public void testEncodeAndParseExtensions() throws Exception {
+
+ org.hl7.fhir.instance.model.Patient patient = new org.hl7.fhir.instance.model.Patient();
+ patient.addIdentifier().setUse(org.hl7.fhir.instance.model.Identifier.IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
+
+ org.hl7.fhir.instance.model.Extension ext = new org.hl7.fhir.instance.model.Extension();
+ ext.setUrl("http://example.com/extensions#someext");
+ ext.setValue(new org.hl7.fhir.instance.model.DateTimeType("2011-01-02T11:13:15"));
+ patient.getExtension().add(ext);
+
+ org.hl7.fhir.instance.model.Extension parent = new org.hl7.fhir.instance.model.Extension().setUrl("http://example.com#parent");
+ patient.getExtension().add(parent);
+ org.hl7.fhir.instance.model.Extension child1 = new org.hl7.fhir.instance.model.Extension().setUrl("http://example.com#child").setValue(new org.hl7.fhir.instance.model.StringType("value1"));
+ parent.getExtension().add(child1);
+ org.hl7.fhir.instance.model.Extension child2 = new org.hl7.fhir.instance.model.Extension().setUrl("http://example.com#child").setValue(new org.hl7.fhir.instance.model.StringType("value2"));
+ parent.getExtension().add(child2);
+
+ org.hl7.fhir.instance.model.Extension modExt = new org.hl7.fhir.instance.model.Extension();
+ modExt.setUrl("http://example.com/extensions#modext");
+ modExt.setValue(new org.hl7.fhir.instance.model.DateType("1995-01-02"));
+ patient.getModifierExtension().add(modExt);
+
+ org.hl7.fhir.instance.model.HumanName name = patient.addName();
+ name.addFamily("Blah");
+ org.hl7.fhir.instance.model.StringType given = name.addGivenElement();
+ given.setValue("Joe");
+ org.hl7.fhir.instance.model.Extension ext2 = new org.hl7.fhir.instance.model.Extension().setUrl("http://examples.com#givenext").setValue(new org.hl7.fhir.instance.model.StringType("given"));
+ given.getExtension().add(ext2);
+
+ org.hl7.fhir.instance.model.StringType given2 = name.addGivenElement();
+ given2.setValue("Shmoe");
+ org.hl7.fhir.instance.model.Extension given2ext = new org.hl7.fhir.instance.model.Extension().setUrl("http://examples.com#givenext_parent");
+ given2.getExtension().add(given2ext);
+ given2ext.addExtension().setUrl("http://examples.com#givenext_child").setValue(new org.hl7.fhir.instance.model.StringType("CHILD"));
+
+ String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
+ ourLog.info(output);
+
+ String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
+ assertThat(enc, containsString(
+ "