diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java
index 351f201e7ac..a75e36357e1 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/TestUtil.java
@@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
-import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;
diff --git a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties
index db8bc3910d4..d1540251b79 100644
--- a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties
+++ b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties
@@ -91,7 +91,11 @@ ca.uhn.fhir.jpa.dao.SearchBuilder.invalidNumberPrefix=Unable to handle number pr
ca.uhn.fhir.jpa.provider.BaseJpaProvider.cantCombintAtAndSince=Unable to combine _at and _since parameters for history operation
+ca.uhn.fhir.jpa.term.BaseHapiTerminologySvcImpl.cannotCreateDuplicateConceptMapUrl=Can not create multiple ConceptMap resources with ConceptMap.url "{0}", already have one with resource ID: {1}
ca.uhn.fhir.jpa.term.BaseHapiTerminologySvcImpl.cannotCreateDuplicateCodeSystemUri=Can not create multiple code systems with URI "{0}", already have one with resource ID: {1}
ca.uhn.fhir.jpa.term.BaseHapiTerminologySvcImpl.expansionTooLarge=Expansion of ValueSet produced too many codes (maximum {0}) - Operation aborted!
-ca.uhn.fhir.jpa.term.BaseHapiTerminologySvcImpl.expansionTooLarge=Expansion of ValueSet produced too many codes (maximum {0}) - Operation aborted!
+ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoConceptMapDstu3.matchesFound=Matches found!
+ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoConceptMapDstu3.noMatchesFound=No matches found!
+ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoConceptMapR4.matchesFound=Matches found!
+ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoConceptMapR4.noMatchesFound=No matches found!
diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml
index 3a3b8566e53..716551302f6 100644
--- a/hapi-fhir-jpaserver-base/pom.xml
+++ b/hapi-fhir-jpaserver-base/pom.xml
@@ -469,6 +469,16 @@
test
+
+ com.github.ben-manes.caffeine
+ caffeine
+
+
+ com.google.guava
+ guava-testlib
+ test
+
+
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
index a42f359a19c..03a7663b141 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
@@ -79,13 +79,8 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
-import javax.annotation.Nullable;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@@ -335,6 +330,13 @@ public abstract class BaseHapiFhirDao implements IDao {
doExpungeEverythingQuery("DELETE from " + TermConceptParentChildLink.class.getSimpleName() + " d");
return null;
});
+ txTemplate.execute(t -> {
+ doExpungeEverythingQuery("DELETE from " + TermConceptMapGroupElementTarget.class.getSimpleName() + " d");
+ doExpungeEverythingQuery("DELETE from " + TermConceptMapGroupElement.class.getSimpleName() + " d");
+ doExpungeEverythingQuery("DELETE from " + TermConceptMapGroup.class.getSimpleName() + " d");
+ doExpungeEverythingQuery("DELETE from " + TermConceptMap.class.getSimpleName() + " d");
+ return null;
+ });
txTemplate.execute(t -> {
doExpungeEverythingQuery("DELETE from " + TermConceptProperty.class.getSimpleName() + " d");
doExpungeEverythingQuery("DELETE from " + TermConceptDesignation.class.getSimpleName() + " d");
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 efa2021cb6f..88d005a4692 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
@@ -57,6 +57,16 @@ public class DaoConfig {
*/
private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null;
private IndexEnabledEnum myIndexMissingFieldsEnabled = IndexEnabledEnum.DISABLED;
+ /**
+ * Default value for {@link #setTranslationCachesExpireAfterWriteInMinutes(Long)}: 60 minutes
+ *
+ * @see #setTranslationCachesExpireAfterWriteInMinutes(Long)
+ */
+ public static final Long DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES = 60L;
+ /**
+ * update setter javadoc if default changes
+ */
+ private Long myTranslationCachesExpireAfterWriteInMinutes = DEFAULT_TRANSLATION_CACHES_EXPIRE_AFTER_WRITE_IN_MINUTES;
/**
* update setter javadoc if default changes
*/
@@ -557,6 +567,22 @@ public class DaoConfig {
myReuseCachedSearchResultsForMillis = theReuseCachedSearchResultsForMillis;
}
+ /**
+ * Specifies the duration in minutes for which values will be retained after being
+ * written to the terminology translation cache. Defaults to 60.
+ */
+ public Long getTranslationCachesExpireAfterWriteInMinutes() {
+ return myTranslationCachesExpireAfterWriteInMinutes;
+ }
+
+ /**
+ * Specifies the duration in minutes for which values will be retained after being
+ * written to the terminology translation cache. Defaults to 60.
+ */
+ public void setTranslationCachesExpireAfterWriteInMinutes(Long translationCachesExpireAfterWriteInMinutes) {
+ myTranslationCachesExpireAfterWriteInMinutes = translationCachesExpireAfterWriteInMinutes;
+ }
+
/**
* This setting may be used to advise the server that any references found in
* resources that have any of the base URLs given here will be replaced with
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirResourceDaoConceptMap.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirResourceDaoConceptMap.java
new file mode 100644
index 00000000000..64aed2891ff
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirResourceDaoConceptMap.java
@@ -0,0 +1,30 @@
+package ca.uhn.fhir.jpa.dao;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import ca.uhn.fhir.jpa.term.TranslationRequest;
+import ca.uhn.fhir.jpa.term.TranslationResult;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+
+public interface IFhirResourceDaoConceptMap extends IFhirResourceDao {
+ TranslationResult translate(TranslationRequest theTranslationRequest, RequestDetails theRequestDetails);
+}
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 e4e3cf21a70..e208c64e1aa 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,6 +28,7 @@ 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.jpa.util.ScrollableResultsIterator;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
@@ -59,9 +60,6 @@ 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;
@@ -2193,7 +2191,7 @@ public class SearchBuilder implements ISearchBuilder {
Query hibernateQuery = (Query) query;
hibernateQuery.setFetchSize(myFetchSize);
ScrollableResults scroll = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
- myResultsIterator = new ScrollableResultsIterator(scroll);
+ myResultsIterator = new ScrollableResultsIterator<>(scroll);
// If the query resulted in extra results being requested
if (myAlsoIncludePids != null) {
@@ -2275,42 +2273,6 @@ public class SearchBuilder implements ISearchBuilder {
}
}
- public class ScrollableResultsIterator extends BaseIterator implements Iterator {
-
- private Long myNext;
- private ScrollableResults myScroll;
-
- public ScrollableResultsIterator(ScrollableResults theScroll) {
- myScroll = theScroll;
- }
-
- private void ensureHaveNext() {
- if (myNext == null) {
- if (myScroll.next()) {
- myNext = (Long) myScroll.get(0);
- } else {
- myNext = NO_MORE;
- }
- }
- }
-
- @Override
- public boolean hasNext() {
- ensureHaveNext();
- return myNext != NO_MORE;
- }
-
- @Override
- public Long next() {
- ensureHaveNext();
- Validate.isTrue(myNext != NO_MORE);
- Long next = myNext;
- myNext = null;
- return next;
- }
-
- }
-
private class UniqueIndexIterator implements Iterator {
private final Set myUniqueQueryStrings;
private Iterator myWrap = null;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapDao.java
new file mode 100644
index 00000000000..e5a037dcd84
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapDao.java
@@ -0,0 +1,41 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+import ca.uhn.fhir.jpa.entity.TermConceptMap;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.Optional;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+public interface ITermConceptMapDao extends JpaRepository {
+ @Query("DELETE FROM TermConceptMap cm WHERE cm.myId = :pid")
+ @Modifying
+ void deleteTermConceptMapById(@Param("pid") Long theId);
+
+ @Query("SELECT cm FROM TermConceptMap cm WHERE cm.myResourcePid = :resource_pid")
+ Optional findTermConceptMapByResourcePid(@Param("resource_pid") Long theResourcePid);
+
+ @Query("SELECT cm FROM TermConceptMap cm WHERE cm.myUrl = :url")
+ Optional findTermConceptMapByUrl(@Param("url") String theUrl);
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupDao.java
new file mode 100644
index 00000000000..ef5e83af470
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupDao.java
@@ -0,0 +1,33 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroup;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+public interface ITermConceptMapGroupDao extends JpaRepository {
+ @Query("DELETE FROM TermConceptMapGroup g WHERE g.myConceptMap.myId = :pid")
+ @Modifying
+ void deleteTermConceptMapGroupById(@Param("pid") Long theId);
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementDao.java
new file mode 100644
index 00000000000..0a659e3a510
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementDao.java
@@ -0,0 +1,33 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+public interface ITermConceptMapGroupElementDao extends JpaRepository {
+ @Query("DELETE FROM TermConceptMapGroupElement e WHERE e.myConceptMapGroup.myConceptMap.myId = :pid")
+ @Modifying
+ void deleteTermConceptMapGroupElementById(@Param("pid") Long theId);
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementTargetDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementTargetDao.java
new file mode 100644
index 00000000000..0900ce61a71
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/ITermConceptMapGroupElementTargetDao.java
@@ -0,0 +1,33 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+public interface ITermConceptMapGroupElementTargetDao extends JpaRepository {
+ @Query("DELETE FROM TermConceptMapGroupElementTarget t WHERE t.myConceptMapGroupElement.myConceptMapGroup.myConceptMap.myId = :pid")
+ @Modifying
+ void deleteTermConceptMapGroupElementTargetById(@Param("pid") Long theId);
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoConceptMapDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoConceptMapDstu3.java
new file mode 100644
index 00000000000..73d0f59a5e4
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoConceptMapDstu3.java
@@ -0,0 +1,176 @@
+package ca.uhn.fhir.jpa.dao.dstu3;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
+import ca.uhn.fhir.jpa.term.TranslationMatch;
+import ca.uhn.fhir.jpa.term.TranslationRequest;
+import ca.uhn.fhir.jpa.term.TranslationResult;
+import ca.uhn.fhir.jpa.entity.ResourceTable;
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
+import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import org.hl7.fhir.convertors.VersionConvertor_30_40;
+import org.hl7.fhir.dstu3.model.ConceptMap;
+import org.hl7.fhir.exceptions.FHIRException;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.r4.model.*;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+
+public class FhirResourceDaoConceptMapDstu3 extends FhirResourceDaoDstu3 implements IFhirResourceDaoConceptMap {
+ @Autowired
+ private IHapiTerminologySvc myHapiTerminologySvc;
+
+ @Override
+ public TranslationResult translate(TranslationRequest theTranslationRequest, RequestDetails theRequestDetails) {
+ if (theTranslationRequest.hasReverse() && theTranslationRequest.getReverseAsBoolean()) {
+ return buildReverseTranslationResult(myHapiTerminologySvc.translateWithReverse(theTranslationRequest));
+ }
+
+ return buildTranslationResult(myHapiTerminologySvc.translate(theTranslationRequest));
+ }
+
+ private TranslationResult buildTranslationResult(List theTargets) {
+ TranslationResult retVal = new TranslationResult();
+
+ String msg;
+ if (theTargets.isEmpty()) {
+
+ retVal.setResult(new BooleanType(false));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapDstu3.class,
+ "noMatchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ } else {
+
+ retVal.setResult(new BooleanType(true));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapDstu3.class,
+ "matchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ TranslationMatch translationMatch;
+ Set targetsToReturn = new HashSet<>();
+ for (TermConceptMapGroupElementTarget target : theTargets) {
+ if (targetsToReturn.add(target)) {
+ translationMatch = new TranslationMatch();
+
+ translationMatch.setEquivalence(new CodeType(target.getEquivalence().toCode()));
+
+ translationMatch.setConcept(
+ new Coding()
+ .setCode(target.getCode())
+ .setSystem(target.getSystem())
+ .setVersion(target.getSystemVersion())
+ .setDisplay(target.getDisplay())
+ );
+
+ translationMatch.setSource(new UriType(target.getConceptMapUrl()));
+
+ retVal.addMatch(translationMatch);
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+ private TranslationResult buildReverseTranslationResult(List theElements) {
+ TranslationResult retVal = new TranslationResult();
+
+ String msg;
+ if (theElements.isEmpty()) {
+
+ retVal.setResult(new BooleanType(false));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapDstu3.class,
+ "noMatchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ } else {
+
+ retVal.setResult(new BooleanType(true));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapDstu3.class,
+ "matchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ TranslationMatch translationMatch;
+ Set elementsToReturn = new HashSet<>();
+ for (TermConceptMapGroupElement element : theElements) {
+ if (elementsToReturn.add(element)) {
+ translationMatch = new TranslationMatch();
+
+ translationMatch.setConcept(
+ new Coding()
+ .setCode(element.getCode())
+ .setSystem(element.getSystem())
+ .setVersion(element.getSystemVersion())
+ .setDisplay(element.getDisplay())
+ );
+
+ translationMatch.setSource(new UriType(element.getConceptMapUrl()));
+
+ retVal.addMatch(translationMatch);
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+ @Override
+ protected ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
+ boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
+ ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
+
+ ConceptMap conceptMap = (ConceptMap) theResource;
+
+ if (conceptMap != null && isNotBlank(conceptMap.getUrl())) {
+ // Convert from DSTU3 to R4
+ try {
+ myHapiTerminologySvc.storeTermConceptMapAndChildren(retVal, VersionConvertor_30_40.convertConceptMap(conceptMap));
+ } catch (FHIRException fe) {
+ throw new InternalErrorException(fe);
+ }
+ }
+
+ return retVal;
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoConceptMapR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoConceptMapR4.java
new file mode 100644
index 00000000000..abe808206cf
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoConceptMapR4.java
@@ -0,0 +1,167 @@
+package ca.uhn.fhir.jpa.dao.r4;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
+import ca.uhn.fhir.jpa.entity.ResourceTable;
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
+import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
+import ca.uhn.fhir.jpa.term.TranslationMatch;
+import ca.uhn.fhir.jpa.term.TranslationRequest;
+import ca.uhn.fhir.jpa.term.TranslationResult;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.r4.model.*;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+
+public class FhirResourceDaoConceptMapR4 extends FhirResourceDaoR4 implements IFhirResourceDaoConceptMap {
+ @Autowired
+ private IHapiTerminologySvc myHapiTerminologySvc;
+
+ @Override
+ public TranslationResult translate(TranslationRequest theTranslationRequest, RequestDetails theRequestDetails) {
+ if (theTranslationRequest.hasReverse() && theTranslationRequest.getReverseAsBoolean()) {
+ return buildReverseTranslationResult(myHapiTerminologySvc.translateWithReverse(theTranslationRequest));
+ }
+
+ return buildTranslationResult(myHapiTerminologySvc.translate(theTranslationRequest));
+ }
+
+ private TranslationResult buildTranslationResult(List theTargets) {
+ TranslationResult retVal = new TranslationResult();
+
+ String msg;
+ if (theTargets.isEmpty()) {
+
+ retVal.setResult(new BooleanType(false));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapR4.class,
+ "noMatchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ } else {
+
+ retVal.setResult(new BooleanType(true));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapR4.class,
+ "matchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ TranslationMatch translationMatch;
+ Set targetsToReturn = new HashSet<>();
+ for (TermConceptMapGroupElementTarget target : theTargets) {
+ if (targetsToReturn.add(target)) {
+ translationMatch = new TranslationMatch();
+
+ translationMatch.setEquivalence(new CodeType(target.getEquivalence().toCode()));
+
+ translationMatch.setConcept(
+ new Coding()
+ .setCode(target.getCode())
+ .setSystem(target.getSystem())
+ .setVersion(target.getSystemVersion())
+ .setDisplay(target.getDisplay())
+ );
+
+ translationMatch.setSource(new UriType(target.getConceptMapUrl()));
+
+ retVal.addMatch(translationMatch);
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+ private TranslationResult buildReverseTranslationResult(List theElements) {
+ TranslationResult retVal = new TranslationResult();
+
+ String msg;
+ if (theElements.isEmpty()) {
+
+ retVal.setResult(new BooleanType(false));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapR4.class,
+ "noMatchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ } else {
+
+ retVal.setResult(new BooleanType(true));
+
+ msg = getContext().getLocalizer().getMessage(
+ FhirResourceDaoConceptMapR4.class,
+ "matchesFound");
+
+ retVal.setMessage(new StringType(msg));
+
+ TranslationMatch translationMatch;
+ Set elementsToReturn = new HashSet<>();
+ for (TermConceptMapGroupElement element : theElements) {
+ if (elementsToReturn.add(element)) {
+ translationMatch = new TranslationMatch();
+
+ translationMatch.setConcept(
+ new Coding()
+ .setCode(element.getCode())
+ .setSystem(element.getSystem())
+ .setVersion(element.getSystemVersion())
+ .setDisplay(element.getDisplay())
+ );
+
+ translationMatch.setSource(new UriType(element.getConceptMapUrl()));
+
+ retVal.addMatch(translationMatch);
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+ @Override
+ protected ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
+ boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
+ ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
+
+ ConceptMap conceptMap = (ConceptMap) theResource;
+
+ if (conceptMap != null && isNotBlank(conceptMap.getUrl())) {
+ myHapiTerminologySvc.storeTermConceptMapAndChildren(retVal, conceptMap);
+ }
+
+ return retVal;
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConcept.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConcept.java
index a329c09df07..b6d5deba6c0 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConcept.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConcept.java
@@ -11,7 +11,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.search.annotations.*;
import org.hl7.fhir.r4.model.Coding;
-import org.springframework.validation.ValidationUtils;
import javax.annotation.Nonnull;
import javax.persistence.*;
@@ -49,7 +48,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
@Index(name = "IDX_CONCEPT_INDEXSTATUS", columnList = "INDEX_STATUS")
})
public class TermConcept implements Serializable {
- private static final int MAX_DESC_LENGTH = 400;
+ protected static final int MAX_DESC_LENGTH = 400;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TermConcept.class);
private static final long serialVersionUID = 1L;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMap.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMap.java
new file mode 100644
index 00000000000..4125bbbf8bf
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMap.java
@@ -0,0 +1,105 @@
+package ca.uhn.fhir.jpa.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@Table(name = "TRM_CONCEPT_MAP", uniqueConstraints = {
+ @UniqueConstraint(name = "IDX_CONCEPT_MAP_URL", columnNames = {"URL"})
+})
+public class TermConceptMap implements Serializable {
+ @Id()
+ @SequenceGenerator(name = "SEQ_CONCEPT_MAP_PID", sequenceName = "SEQ_CONCEPT_MAP_PID")
+ @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_MAP_PID")
+ @Column(name = "PID")
+ private Long myId;
+
+ @OneToOne()
+ @JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_TRMCONCEPTMAP_RES"))
+ private ResourceTable myResource;
+
+ @Column(name = "RES_ID", insertable = false, updatable = false)
+ private Long myResourcePid;
+
+ @Column(name = "SOURCE_URL", nullable = false, length = 200)
+ private String mySource;
+
+ @Column(name = "TARGET_URL", nullable = false, length = 200)
+ private String myTarget;
+
+ @Column(name = "URL", length = 200)
+ private String myUrl;
+
+ @OneToMany(mappedBy = "myConceptMap")
+ private List myConceptMapGroups;
+
+ public List getConceptMapGroups() {
+ if (myConceptMapGroups == null) {
+ myConceptMapGroups = new ArrayList<>();
+ }
+
+ return myConceptMapGroups;
+ }
+
+ public Long getId() {
+ return myId;
+ }
+
+ public ResourceTable getResource() {
+ return myResource;
+ }
+
+ public void setResource(ResourceTable resource) {
+ myResource = resource;
+ }
+
+ public Long getResourcePid() {
+ return myResourcePid;
+ }
+
+ public void setResourcePid(Long resourcePid) {
+ myResourcePid = resourcePid;
+ }
+
+ public String getSource() {
+ return mySource;
+ }
+
+ public void setSource(String source) {
+ mySource = source;
+ }
+
+ public String getTarget() {
+ return myTarget;
+ }
+
+ public void setTarget(String target) {
+ myTarget = target;
+ }
+
+ public String getUrl() {
+ return myUrl;
+ }
+
+ public void setUrl(String theUrl) {
+ myUrl = theUrl;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+ .append("myId", myId)
+ .append("myResource", myResource.toString())
+ .append("myResourcePid", myResourcePid)
+ .append("mySource", mySource)
+ .append("myTarget", myTarget)
+ .append("myUrl", myUrl)
+ .append("myConceptMapGroups - size", myConceptMapGroups.size())
+ .toString();
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroup.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroup.java
new file mode 100644
index 00000000000..474fd06d39e
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroup.java
@@ -0,0 +1,131 @@
+package ca.uhn.fhir.jpa.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@Table(name = "TRM_CONCEPT_MAP_GROUP")
+public class TermConceptMapGroup implements Serializable {
+ @Id()
+ @SequenceGenerator(name = "SEQ_CONCEPT_MAP_GROUP_PID", sequenceName = "SEQ_CONCEPT_MAP_GROUP_PID")
+ @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_MAP_GROUP_PID")
+ @Column(name = "PID")
+ private Long myId;
+
+ @ManyToOne()
+ @JoinColumn(name = "CONCEPT_MAP_PID", nullable = false, referencedColumnName = "PID", foreignKey=@ForeignKey(name="FK_TCMGROUP_CONCEPTMAP"))
+ private TermConceptMap myConceptMap;
+
+ @Column(name = "SOURCE_URL", nullable = false, length = 200)
+ private String mySource;
+
+ @Column(name = "SOURCE_VERSION", length = 50)
+ private String mySourceVersion;
+
+ @Column(name = "TARGET_URL", nullable = false, length = 200)
+ private String myTarget;
+
+ @Column(name = "TARGET_VERSION", length = 50)
+ private String myTargetVersion;
+
+ @OneToMany(mappedBy = "myConceptMapGroup")
+ private List myConceptMapGroupElements;
+
+ private String myConceptMapUrl;
+ private String mySourceValueSet;
+ private String myTargetValueSet;
+
+ public TermConceptMap getConceptMap() {
+ return myConceptMap;
+ }
+
+ public void setConceptMap(TermConceptMap theTermConceptMap) {
+ myConceptMap = theTermConceptMap;
+ }
+
+ public List getConceptMapGroupElements() {
+ if (myConceptMapGroupElements == null) {
+ myConceptMapGroupElements = new ArrayList<>();
+ }
+
+ return myConceptMapGroupElements;
+ }
+
+ public String getConceptMapUrl() {
+ if (myConceptMapUrl == null) {
+ myConceptMapUrl = getConceptMap().getUrl();
+ }
+ return myConceptMapUrl;
+ }
+
+ public Long getId() {
+ return myId;
+ }
+
+ public String getSource() {
+ return mySource;
+ }
+
+ public void setSource(String theSource) {
+ this.mySource = theSource;
+ }
+
+ public String getSourceValueSet() {
+ if (mySourceValueSet == null) {
+ mySourceValueSet = getConceptMap().getSource();
+ }
+ return mySourceValueSet;
+ }
+
+ public String getSourceVersion() {
+ return mySourceVersion;
+ }
+
+ public void setSourceVersion(String theSourceVersion) {
+ mySourceVersion = theSourceVersion;
+ }
+
+ public String getTarget() {
+ return myTarget;
+ }
+
+ public void setTarget(String theTarget) {
+ this.myTarget = theTarget;
+ }
+
+ public String getTargetValueSet() {
+ if (myTargetValueSet == null) {
+ myTargetValueSet = getConceptMap().getTarget();
+ }
+ return myTargetValueSet;
+ }
+
+ public String getTargetVersion() {
+ return myTargetVersion;
+ }
+
+ public void setTargetVersion(String theTargetVersion) {
+ myTargetVersion = theTargetVersion;
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+ .append("myId", myId)
+ .append("myConceptMap - id", myConceptMap.getId())
+ .append("mySource", mySource)
+ .append("mySourceVersion", mySourceVersion)
+ .append("myTarget", myTarget)
+ .append("myTargetVersion", myTargetVersion)
+ .append("myConceptMapGroupElements - size", myConceptMapGroupElements.size())
+ .append("myConceptMapUrl", this.getConceptMapUrl())
+ .append("mySourceValueSet", this.getSourceValueSet())
+ .append("myTargetValueSet", this.getTargetValueSet())
+ .toString();
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroupElement.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroupElement.java
new file mode 100644
index 00000000000..5e038e2c7dc
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroupElement.java
@@ -0,0 +1,144 @@
+package ca.uhn.fhir.jpa.entity;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@Table(name = "TRM_CONCEPT_MAP_GRP_ELEMENT", indexes = {
+ @Index(name = "IDX_CNCPT_MAP_GRP_CD", columnList = "SOURCE_CODE")
+})
+public class TermConceptMapGroupElement implements Serializable {
+ @Id()
+ @SequenceGenerator(name = "SEQ_CONCEPT_MAP_GRP_ELM_PID", sequenceName = "SEQ_CONCEPT_MAP_GRP_ELM_PID")
+ @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_MAP_GRP_ELM_PID")
+ @Column(name = "PID")
+ private Long myId;
+
+ @ManyToOne()
+ @JoinColumn(name = "CONCEPT_MAP_GROUP_PID", nullable = false, referencedColumnName = "PID", foreignKey=@ForeignKey(name="FK_TCMGELEMENT_GROUP"))
+ private TermConceptMapGroup myConceptMapGroup;
+
+ @Column(name = "SOURCE_CODE", nullable = false, length = 50)
+ private String myCode;
+
+ @Column(name = "SOURCE_DISPLAY", length = TermConcept.MAX_DESC_LENGTH)
+ private String myDisplay;
+
+ @OneToMany(mappedBy = "myConceptMapGroupElement")
+ private List myConceptMapGroupElementTargets;
+
+ private String myConceptMapUrl;
+ private String mySystem;
+ private String mySystemVersion;
+ private String myValueSet;
+
+ public String getCode() {
+ return myCode;
+ }
+
+ public void setCode(String theCode) {
+ myCode = theCode;
+ }
+
+ public TermConceptMapGroup getConceptMapGroup() {
+ return myConceptMapGroup;
+ }
+
+ public void setConceptMapGroup(TermConceptMapGroup theTermConceptMapGroup) {
+ myConceptMapGroup = theTermConceptMapGroup;
+ }
+
+ public List getConceptMapGroupElementTargets() {
+ if (myConceptMapGroupElementTargets == null) {
+ myConceptMapGroupElementTargets = new ArrayList<>();
+ }
+
+ return myConceptMapGroupElementTargets;
+ }
+
+ public String getConceptMapUrl() {
+ if (myConceptMapUrl == null) {
+ myConceptMapUrl = getConceptMapGroup().getConceptMap().getUrl();
+ }
+ return myConceptMapUrl;
+ }
+
+ public String getDisplay() {
+ return myDisplay;
+ }
+
+ public void setDisplay(String theDisplay) {
+ myDisplay = theDisplay;
+ }
+
+ public Long getId() {
+ return myId;
+ }
+
+ public String getSystem() {
+ if (mySystem == null) {
+ mySystem = getConceptMapGroup().getSource();
+ }
+ return mySystem;
+ }
+
+ public String getSystemVersion() {
+ if (mySystemVersion == null) {
+ mySystemVersion = getConceptMapGroup().getSourceVersion();
+ }
+ return mySystemVersion;
+ }
+
+ public String getValueSet() {
+ if (myValueSet == null) {
+ myValueSet = getConceptMapGroup().getSourceValueSet();
+ }
+ return myValueSet;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (!(o instanceof TermConceptMapGroupElement)) return false;
+
+ TermConceptMapGroupElement that = (TermConceptMapGroupElement) o;
+
+ return new EqualsBuilder()
+ .append(getCode(), that.getCode())
+ .append(getSystem(), that.getSystem())
+ .append(getSystemVersion(), that.getSystemVersion())
+ .isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37)
+ .append(getCode())
+ .append(getSystem())
+ .append(getSystemVersion())
+ .toHashCode();
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+ .append("myId", myId)
+ .append("myConceptMapGroup - id", myConceptMapGroup.getId())
+ .append("myCode", myCode)
+ .append("myDisplay", myDisplay)
+ .append("myConceptMapGroupElementTargets - size", myConceptMapGroupElementTargets.size())
+ .append("myConceptMapUrl", this.getConceptMapUrl())
+ .append("mySystem", this.getSystem())
+ .append("mySystemVersion", this.getSystemVersion())
+ .append("myValueSet", this.getValueSet())
+ .toString();
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroupElementTarget.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroupElementTarget.java
new file mode 100644
index 00000000000..f0a78e49bca
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermConceptMapGroupElementTarget.java
@@ -0,0 +1,146 @@
+package ca.uhn.fhir.jpa.entity;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+@Table(name = "TRM_CONCEPT_MAP_GRP_ELM_TGT", indexes = {
+ @Index(name = "IDX_CNCPT_MP_GRP_ELM_TGT_CD", columnList = "TARGET_CODE")
+})
+public class TermConceptMapGroupElementTarget implements Serializable {
+ @Id()
+ @SequenceGenerator(name = "SEQ_CNCPT_MAP_GRP_ELM_TGT_PID", sequenceName = "SEQ_CNCPT_MAP_GRP_ELM_TGT_PID")
+ @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CNCPT_MAP_GRP_ELM_TGT_PID")
+ @Column(name = "PID")
+ private Long myId;
+
+ @ManyToOne()
+ @JoinColumn(name = "CONCEPT_MAP_GRP_ELM_PID", nullable = false, referencedColumnName = "PID", foreignKey=@ForeignKey(name="FK_TCMGETARGET_ELEMENT"))
+ private TermConceptMapGroupElement myConceptMapGroupElement;
+
+ @Column(name = "TARGET_CODE", nullable = false, length = 50)
+ private String myCode;
+
+ @Column(name = "TARGET_DISPLAY", length = TermConcept.MAX_DESC_LENGTH)
+ private String myDisplay;
+
+ @Enumerated(EnumType.STRING)
+ @Column(name = "TARGET_EQUIVALENCE", length = 50)
+ private ConceptMapEquivalence myEquivalence;
+
+ private String myConceptMapUrl;
+ private String mySystem;
+ private String mySystemVersion;
+ private String myValueSet;
+
+ public String getCode() {
+ return myCode;
+ }
+
+ public void setCode(String theCode) {
+ myCode = theCode;
+ }
+
+ public TermConceptMapGroupElement getConceptMapGroupElement() {
+ return myConceptMapGroupElement;
+ }
+
+ public void setConceptMapGroupElement(TermConceptMapGroupElement theTermConceptMapGroupElement) {
+ myConceptMapGroupElement = theTermConceptMapGroupElement;
+ }
+
+ public String getConceptMapUrl() {
+ if (myConceptMapUrl == null) {
+ myConceptMapUrl = getConceptMapGroupElement().getConceptMapGroup().getConceptMap().getUrl();
+ }
+ return myConceptMapUrl;
+ }
+
+ public String getDisplay() {
+ return myDisplay;
+ }
+
+ public void setDisplay(String theDisplay) {
+ myDisplay = theDisplay;
+ }
+
+ public ConceptMapEquivalence getEquivalence() {
+ return myEquivalence;
+ }
+
+ public void setEquivalence(ConceptMapEquivalence theEquivalence) {
+ myEquivalence = theEquivalence;
+ }
+
+ public Long getId() {
+ return myId;
+ }
+
+ public String getSystem() {
+ if (mySystem == null) {
+ mySystem = getConceptMapGroupElement().getConceptMapGroup().getTarget();
+ }
+ return mySystem;
+ }
+
+ public String getSystemVersion() {
+ if (mySystemVersion == null) {
+ mySystemVersion = getConceptMapGroupElement().getConceptMapGroup().getTargetVersion();
+ }
+ return mySystemVersion;
+ }
+
+ public String getValueSet() {
+ if (myValueSet == null) {
+ myValueSet = getConceptMapGroupElement().getConceptMapGroup().getTargetValueSet();
+ }
+ return myValueSet;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (!(o instanceof TermConceptMapGroupElementTarget)) return false;
+
+ TermConceptMapGroupElementTarget that = (TermConceptMapGroupElementTarget) o;
+
+ return new EqualsBuilder()
+ .append(getCode(), that.getCode())
+ .append(getEquivalence(), that.getEquivalence())
+ .append(getSystem(), that.getSystem())
+ .append(getSystemVersion(), that.getSystemVersion())
+ .isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37)
+ .append(getCode())
+ .append(getEquivalence())
+ .append(getSystem())
+ .append(getSystemVersion())
+ .toHashCode();
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+ .append("myId", myId)
+ .append("myConceptMapGroupElement - id", myConceptMapGroupElement.getId())
+ .append("myCode", myCode)
+ .append("myDisplay", myDisplay)
+ .append("myEquivalence", myEquivalence.toCode())
+ .append("myConceptMapUrl", this.getConceptMapUrl())
+ .append("mySystem", this.getSystem())
+ .append("mySystemVersion", this.getSystemVersion())
+ .append("myValueSet", this.getValueSet())
+ .toString();
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderConceptMapDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderConceptMapDstu3.java
new file mode 100644
index 00000000000..82c766ce353
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderConceptMapDstu3.java
@@ -0,0 +1,153 @@
+package ca.uhn.fhir.jpa.provider.dstu3;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
+import ca.uhn.fhir.jpa.term.TranslationRequest;
+import ca.uhn.fhir.jpa.term.TranslationResult;
+import ca.uhn.fhir.jpa.util.JpaConstants;
+import ca.uhn.fhir.rest.annotation.IdParam;
+import ca.uhn.fhir.rest.annotation.Operation;
+import ca.uhn.fhir.rest.annotation.OperationParam;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import org.hl7.fhir.convertors.VersionConvertor_30_40;
+import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.exceptions.FHIRException;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderDstu3 {
+ @Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = {
+ @OperationParam(name = "result", type = BooleanType.class, min = 1, max = 1),
+ @OperationParam(name = "message", type = StringType.class, min = 0, max = 1),
+ })
+ public Parameters translate(
+ HttpServletRequest theServletRequest,
+ @IdParam(optional = true) IdType theId,
+ @OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode,
+ @OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem,
+ @OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion,
+ @OperationParam(name = "source", min = 0, max = 1) UriType theSourceValueSet,
+ @OperationParam(name = "coding", min = 0, max = 1) Coding theSourceCoding,
+ @OperationParam(name = "codeableConcept", min = 0, max = 1) CodeableConcept theSourceCodeableConcept,
+ @OperationParam(name = "target", min = 0, max = 1) UriType theTargetValueSet,
+ @OperationParam(name = "targetsystem", min = 0, max = 1) UriType theTargetCodeSystem,
+ @OperationParam(name = "reverse", min = 0, max = 1) BooleanType theReverse,
+ RequestDetails theRequestDetails
+ ) {
+ boolean haveSourceCode = theSourceCode != null
+ && theSourceCode.hasValue();
+ boolean haveSourceCodeSystem = theSourceCodeSystem != null
+ && theSourceCodeSystem.hasValue();
+ boolean haveSourceCodeSystemVersion = theSourceCodeSystemVersion != null
+ && theSourceCodeSystemVersion.hasValue();
+ boolean haveSourceValueSet = theSourceValueSet != null
+ && theSourceValueSet.hasValue();
+ boolean haveSourceCoding = theSourceCoding != null
+ && theSourceCoding.hasCode();
+ boolean haveSourceCodeableConcept= theSourceCodeableConcept != null
+ && theSourceCodeableConcept.hasCoding()
+ && theSourceCodeableConcept.getCodingFirstRep().hasCode();
+ boolean haveTargetValueSet = theTargetValueSet != null
+ && theTargetValueSet.hasValue();
+ boolean haveTargetCodeSystem = theTargetCodeSystem != null
+ && theTargetCodeSystem.hasValue();
+ boolean haveReverse = theReverse != null;
+ boolean haveId = theId != null && theId.hasIdPart();
+
+ //
+ if ((!haveSourceCode && !haveSourceCoding && !haveSourceCodeableConcept)
+ || moreThanOneTrue(haveSourceCode, haveSourceCoding, haveSourceCodeableConcept)) {
+ throw new InvalidRequestException("One (and only one) of the in parameters (code, coding, codeableConcept) must be provided, to identify the code that is to be translated.");
+ }
+
+ TranslationRequest translationRequest = new TranslationRequest();
+ try {
+ // Convert from DSTU3 to R4
+ if (haveSourceCode) {
+ translationRequest.getCodeableConcept().addCoding().setCodeElement(VersionConvertor_30_40.convertCode(theSourceCode));
+
+ if (haveSourceCodeSystem) {
+ translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement(VersionConvertor_30_40.convertUri(theSourceCodeSystem));
+ }
+
+ if (haveSourceCodeSystemVersion) {
+ translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement(VersionConvertor_30_40.convertString(theSourceCodeSystemVersion));
+ }
+ } else if (haveSourceCoding) {
+ translationRequest.getCodeableConcept().addCoding(VersionConvertor_30_40.convertCoding(theSourceCoding));
+ } else {
+ translationRequest.setCodeableConcept(VersionConvertor_30_40.convertCodeableConcept(theSourceCodeableConcept));
+ }
+
+ if (haveSourceValueSet) {
+ translationRequest.setSource(VersionConvertor_30_40.convertUri(theSourceValueSet));
+ }
+
+ if (haveTargetValueSet) {
+ translationRequest.setTarget(VersionConvertor_30_40.convertUri(theTargetValueSet));
+ }
+
+ if (haveTargetCodeSystem) {
+ translationRequest.setTargetSystem(VersionConvertor_30_40.convertUri(theTargetCodeSystem));
+ }
+
+ if (haveReverse) {
+ translationRequest.setReverse(VersionConvertor_30_40.convertBoolean(theReverse));
+ }
+
+ if (haveId) {
+ translationRequest.setResourceId(theId.getIdPartAsLong());
+ }
+ } catch (FHIRException fe) {
+ throw new InternalErrorException(fe);
+ }
+
+ startRequest(theServletRequest);
+ try {
+ IFhirResourceDaoConceptMap dao = (IFhirResourceDaoConceptMap) getDao();
+ TranslationResult result = dao.translate(translationRequest, theRequestDetails);
+
+ // Convert from R4 to DSTU3
+ return VersionConvertor_30_40.convertParameters(result.toParameters());
+ } catch (FHIRException fe) {
+ throw new InternalErrorException(fe);
+ } finally {
+ endRequest(theServletRequest);
+ }
+ }
+
+ private static boolean moreThanOneTrue(boolean... theBooleans) {
+ boolean haveOne = false;
+ for (boolean next : theBooleans) {
+ if (next) {
+ if (haveOne) {
+ return true;
+ } else {
+ haveOne = true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderConceptMapR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderConceptMapR4.java
new file mode 100644
index 00000000000..57f5cc883c9
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderConceptMapR4.java
@@ -0,0 +1,142 @@
+package ca.uhn.fhir.jpa.provider.r4;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import ca.uhn.fhir.jpa.dao.IFhirResourceDaoConceptMap;
+import ca.uhn.fhir.jpa.term.TranslationRequest;
+import ca.uhn.fhir.jpa.term.TranslationResult;
+import ca.uhn.fhir.jpa.util.JpaConstants;
+import ca.uhn.fhir.rest.annotation.IdParam;
+import ca.uhn.fhir.rest.annotation.Operation;
+import ca.uhn.fhir.rest.annotation.OperationParam;
+import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import org.hl7.fhir.r4.model.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class BaseJpaResourceProviderConceptMapR4 extends JpaResourceProviderR4 {
+ @Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = {
+ @OperationParam(name = "result", type = BooleanType.class, min = 1, max = 1),
+ @OperationParam(name = "message", type = StringType.class, min = 0, max = 1),
+ })
+ public Parameters translate(
+ HttpServletRequest theServletRequest,
+ @IdParam(optional = true) IdType theId,
+ @OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode,
+ @OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem,
+ @OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion,
+ @OperationParam(name = "source", min = 0, max = 1) UriType theSourceValueSet,
+ @OperationParam(name = "coding", min = 0, max = 1) Coding theSourceCoding,
+ @OperationParam(name = "codeableConcept", min = 0, max = 1) CodeableConcept theSourceCodeableConcept,
+ @OperationParam(name = "target", min = 0, max = 1) UriType theTargetValueSet,
+ @OperationParam(name = "targetsystem", min = 0, max = 1) UriType theTargetCodeSystem,
+ @OperationParam(name = "reverse", min = 0, max = 1) BooleanType theReverse,
+ RequestDetails theRequestDetails
+ ) {
+ boolean haveSourceCode = theSourceCode != null
+ && theSourceCode.hasCode();
+ boolean haveSourceCodeSystem = theSourceCodeSystem != null
+ && theSourceCodeSystem.hasValue();
+ boolean haveSourceCodeSystemVersion = theSourceCodeSystemVersion != null
+ && theSourceCodeSystemVersion.hasValue();
+ boolean haveSourceValueSet = theSourceValueSet != null
+ && theSourceValueSet.hasValue();
+ boolean haveSourceCoding = theSourceCoding != null
+ && theSourceCoding.hasCode();
+ boolean haveSourceCodeableConcept= theSourceCodeableConcept != null
+ && theSourceCodeableConcept.hasCoding()
+ && theSourceCodeableConcept.getCodingFirstRep().hasCode();
+ boolean haveTargetValueSet = theTargetValueSet != null
+ && theTargetValueSet.hasValue();
+ boolean haveTargetCodeSystem = theTargetCodeSystem != null
+ && theTargetCodeSystem.hasValue();
+ boolean haveReverse = theReverse != null;
+ boolean haveId = theId != null && theId.hasIdPart();
+
+ //
+ if ((!haveSourceCode && !haveSourceCoding && !haveSourceCodeableConcept)
+ || moreThanOneTrue(haveSourceCode, haveSourceCoding, haveSourceCodeableConcept)) {
+ throw new InvalidRequestException("One (and only one) of the in parameters (code, coding, codeableConcept) must be provided, to identify the code that is to be translated.");
+ }
+
+ TranslationRequest translationRequest = new TranslationRequest();
+
+ if (haveSourceCode) {
+ translationRequest.getCodeableConcept().addCoding().setCodeElement(theSourceCode);
+
+ if (haveSourceCodeSystem) {
+ translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement(theSourceCodeSystem);
+ }
+
+ if (haveSourceCodeSystemVersion) {
+ translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement(theSourceCodeSystemVersion);
+ }
+ } else if (haveSourceCoding) {
+ translationRequest.getCodeableConcept().addCoding(theSourceCoding);
+ } else {
+ translationRequest.setCodeableConcept(theSourceCodeableConcept);
+ }
+
+ if (haveSourceValueSet) {
+ translationRequest.setSource(theSourceValueSet);
+ }
+
+ if (haveTargetValueSet) {
+ translationRequest.setTarget(theTargetValueSet);
+ }
+
+ if (haveTargetCodeSystem) {
+ translationRequest.setTargetSystem(theTargetCodeSystem);
+ }
+
+ if (haveReverse) {
+ translationRequest.setReverse(theReverse);
+ }
+
+ if (haveId) {
+ translationRequest.setResourceId(theId.getIdPartAsLong());
+ }
+
+ startRequest(theServletRequest);
+ try {
+ IFhirResourceDaoConceptMap dao = (IFhirResourceDaoConceptMap) getDao();
+ TranslationResult result = dao.translate(translationRequest, theRequestDetails);
+ return result.toParameters();
+ } finally {
+ endRequest(theServletRequest);
+ }
+ }
+
+ private static boolean moreThanOneTrue(boolean... theBooleans) {
+ boolean haveOne = false;
+ for (boolean next : theBooleans) {
+ if (next) {
+ if (haveOne) {
+ return true;
+ } else {
+ haveOne = true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java
index 202c0c0bf13..59c4b9f819c 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java
@@ -27,24 +27,32 @@ import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
+import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
import ca.uhn.fhir.rest.api.server.RequestDetails;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.ObjectUtil;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.ValidateUtil;
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ArrayListMultimap;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.lucene.search.Query;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.QueryBuilder;
+import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeSystem;
+import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ValueSet;
import org.springframework.beans.factory.annotation.Autowired;
@@ -58,9 +66,12 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
+import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -69,14 +80,26 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc {
+ public static final int DEFAULT_FETCH_SIZE = 250;
+
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiTerminologySvcImpl.class);
private static final Object PLACEHOLDER_OBJECT = new Object();
private static boolean ourForceSaveDeferredAlwaysForUnitTest;
+ private static boolean ourLastResultsFromTranslationCache; // For testing.
+ private static boolean ourLastResultsFromTranslationWithReverseCache; // For testing.
@Autowired
protected ITermCodeSystemDao myCodeSystemDao;
@Autowired
protected ITermConceptDao myConceptDao;
@Autowired
+ protected ITermConceptMapDao myConceptMapDao;
+ @Autowired
+ protected ITermConceptMapGroupDao myConceptMapGroupDao;
+ @Autowired
+ protected ITermConceptMapGroupElementDao myConceptMapGroupElementDao;
+ @Autowired
+ protected ITermConceptMapGroupElementTargetDao myConceptMapGroupElementTargetDao;
+ @Autowired
protected ITermConceptPropertyDao myConceptPropertyDao;
@Autowired
protected ITermConceptDesignationDao myConceptDesignationDao;
@@ -102,6 +125,12 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
@Autowired(required = false)
private IFhirResourceDaoCodeSystem, ?, ?> myCodeSystemResourceDao;
+ private Cache> myTranslationCache;
+ private Cache> myTranslationWithReverseCache;
+
+
+ private int myFetchSize = DEFAULT_FETCH_SIZE;
+
private void addCodeIfNotAlreadyAdded(String theCodeSystem, ValueSet.ValueSetExpansionComponent theExpansionComponent, Set theAddedCodes, TermConcept theConcept) {
if (theAddedCodes.add(theConcept.getCode())) {
ValueSet.ValueSetExpansionContainsComponent contains = theExpansionComponent.addContains();
@@ -160,6 +189,23 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
return retVal;
}
+ @PostConstruct
+ public void buildTranslationCaches() {
+ Long timeout = myDaoConfig.getTranslationCachesExpireAfterWriteInMinutes();
+
+ myTranslationCache =
+ Caffeine.newBuilder()
+ .maximumSize(10000)
+ .expireAfterWrite(timeout, TimeUnit.MINUTES)
+ .build();
+
+ myTranslationWithReverseCache =
+ Caffeine.newBuilder()
+ .maximumSize(10000)
+ .expireAfterWrite(timeout, TimeUnit.MINUTES)
+ .build();
+ }
+
protected abstract IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource);
protected abstract void createOrUpdateConceptMap(ConceptMap theNextConceptMap);
@@ -869,6 +915,112 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
return csId;
}
+ @Override
+ @Transactional
+ public void storeTermConceptMapAndChildren(ResourceTable theResourceTable, ConceptMap theConceptMap) {
+ ourLog.info("Storing TermConceptMap...");
+
+ ValidateUtil.isTrueOrThrowInvalidRequest(theResourceTable != null, "No resource supplied.");
+ ValidateUtil.isNotBlankOrThrowInvalidRequest(theConceptMap.getUrl(), "No URL supplied.");
+
+ TermConceptMap termConceptMap = new TermConceptMap();
+ termConceptMap.setResource(theResourceTable);
+ termConceptMap.setUrl(theConceptMap.getUrl());
+
+ // Get existing entity so it can be deleted.
+ Optional optionalExistingTermConceptMapById = myConceptMapDao.findTermConceptMapByResourcePid(termConceptMap.getResourcePid());
+
+ /*
+ * For now we always delete old versions. At some point, it would be nice to allow configuration to keep old versions.
+ */
+
+ if (optionalExistingTermConceptMapById.isPresent()) {
+ Long id = optionalExistingTermConceptMapById.get().getId();
+ ourLog.info("Deleting existing TermConceptMap {} and its children...", id);
+ myConceptMapGroupElementTargetDao.deleteTermConceptMapGroupElementTargetById(id);
+ myConceptMapGroupElementDao.deleteTermConceptMapGroupElementById(id);
+ myConceptMapGroupDao.deleteTermConceptMapGroupById(id);
+ myConceptMapDao.deleteTermConceptMapById(id);
+ ourLog.info("Done deleting existing TermConceptMap {} and its children.", id);
+
+ ourLog.info("Flushing...");
+ myConceptMapGroupElementTargetDao.flush();
+ myConceptMapGroupElementDao.flush();
+ myConceptMapGroupDao.flush();
+ myConceptMapDao.flush();
+ ourLog.info("Done flushing.");
+ }
+
+ /*
+ * Do the upload.
+ */
+ String conceptMapUrl = termConceptMap.getUrl();
+ Optional optionalExistingTermConceptMapByUrl = myConceptMapDao.findTermConceptMapByUrl(conceptMapUrl);
+ if (!optionalExistingTermConceptMapByUrl.isPresent()) {
+ try {
+ String source = theConceptMap.getSourceUriType().getValueAsString();
+ if (isNotBlank(source)) {
+ termConceptMap.setSource(source);
+ }
+ String target = theConceptMap.getTargetUriType().getValueAsString();
+ if (isNotBlank(target)) {
+ termConceptMap.setTarget(target);
+ }
+ } catch (FHIRException fe) {
+ throw new InternalErrorException(fe);
+ }
+ myConceptMapDao.save(termConceptMap);
+
+ if (theConceptMap.hasGroup()) {
+ TermConceptMapGroup termConceptMapGroup;
+ for (ConceptMap.ConceptMapGroupComponent group : theConceptMap.getGroup()) {
+ termConceptMapGroup = new TermConceptMapGroup();
+ termConceptMapGroup.setConceptMap(termConceptMap);
+ termConceptMapGroup.setSource(group.getSource());
+ termConceptMapGroup.setSourceVersion(group.getSourceVersion());
+ termConceptMapGroup.setTarget(group.getTarget());
+ termConceptMapGroup.setTargetVersion(group.getTargetVersion());
+ myConceptMapGroupDao.save(termConceptMapGroup);
+
+ if (group.hasElement()) {
+ TermConceptMapGroupElement termConceptMapGroupElement;
+ for (ConceptMap.SourceElementComponent element : group.getElement()) {
+ termConceptMapGroupElement = new TermConceptMapGroupElement();
+ termConceptMapGroupElement.setConceptMapGroup(termConceptMapGroup);
+ termConceptMapGroupElement.setCode(element.getCode());
+ termConceptMapGroupElement.setDisplay(element.getDisplay());
+ myConceptMapGroupElementDao.save(termConceptMapGroupElement);
+
+ if (element.hasTarget()) {
+ TermConceptMapGroupElementTarget termConceptMapGroupElementTarget;
+ for (ConceptMap.TargetElementComponent target : element.getTarget()) {
+ termConceptMapGroupElementTarget = new TermConceptMapGroupElementTarget();
+ termConceptMapGroupElementTarget.setConceptMapGroupElement(termConceptMapGroupElement);
+ termConceptMapGroupElementTarget.setCode(target.getCode());
+ termConceptMapGroupElementTarget.setDisplay(target.getDisplay());
+ termConceptMapGroupElementTarget.setEquivalence(target.getEquivalence());
+ myConceptMapGroupElementTargetDao.saveAndFlush(termConceptMapGroupElementTarget);
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ TermConceptMap existingTermConceptMap = optionalExistingTermConceptMapByUrl.get();
+
+ String msg = myContext.getLocalizer().getMessage(
+ BaseHapiTerminologySvcImpl.class,
+ "cannotCreateDuplicateConceptMapUrl",
+ conceptMapUrl,
+ existingTermConceptMap.getResourcePid());
+
+ throw new UnprocessableEntityException(msg);
+ }
+
+ ourLog.info("Done storing TermConceptMap.");
+ }
+
@Override
public boolean supportsSystem(String theSystem) {
TermCodeSystem cs = getCodeSystem(theSystem);
@@ -883,6 +1035,166 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
return retVal;
}
+ @Override
+ public List translate(TranslationRequest theTranslationRequest) {
+ List retVal = new ArrayList<>();
+
+ CriteriaBuilder criteriaBuilder = myEntityManager.getCriteriaBuilder();
+ CriteriaQuery query = criteriaBuilder.createQuery(TermConceptMapGroupElementTarget.class);
+ Root root = query.from(TermConceptMapGroupElementTarget.class);
+
+ Join elementJoin = root.join("myConceptMapGroupElement");
+ Join groupJoin = elementJoin.join("myConceptMapGroup");
+ Join conceptMapJoin = groupJoin.join("myConceptMap");
+
+ List translationQueries = theTranslationRequest.getTranslationQueries();
+ List cachedTargets;
+ ArrayList predicates;
+ Coding coding;
+ for (TranslationQuery translationQuery : translationQueries) {
+ cachedTargets = myTranslationCache.getIfPresent(translationQuery);
+ if (cachedTargets == null) {
+ final List targets = new ArrayList<>();
+
+ predicates = new ArrayList<>();
+
+ coding = translationQuery.getCoding();
+ if (coding.hasCode()) {
+ predicates.add(criteriaBuilder.equal(elementJoin.get("myCode"), coding.getCode()));
+ } else {
+ throw new InvalidRequestException("A code must be provided for translation to occur.");
+ }
+
+ if (coding.hasSystem()) {
+ predicates.add(criteriaBuilder.equal(groupJoin.get("mySource"), coding.getSystem()));
+ }
+
+ if (coding.hasVersion()) {
+ predicates.add(criteriaBuilder.equal(groupJoin.get("mySourceVersion"), coding.getVersion()));
+ }
+
+ if (translationQuery.hasTargetSystem()) {
+ predicates.add(criteriaBuilder.equal(groupJoin.get("myTarget"), translationQuery.getTargetSystem().getValueAsString()));
+ }
+
+ if (translationQuery.hasSource()) {
+ predicates.add(criteriaBuilder.equal(conceptMapJoin.get("mySource"), translationQuery.getSource().getValueAsString()));
+ }
+
+ if (translationQuery.hasTarget()) {
+ predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myTarget"), translationQuery.getTarget().getValueAsString()));
+ }
+
+ if (translationQuery.hasResourceId()) {
+ predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myResourcePid"), translationQuery.getResourceId()));
+ }
+
+ Predicate outerPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[0]));
+ query.where(outerPredicate);
+
+ // Use scrollable results.
+ final TypedQuery typedQuery = myEntityManager.createQuery(query.select(root));
+ org.hibernate.query.Query hibernateQuery = (org.hibernate.query.Query) typedQuery;
+ hibernateQuery.setFetchSize(myFetchSize);
+ ScrollableResults scrollableResults = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
+ Iterator scrollableResultsIterator = new ScrollableResultsIterator<>(scrollableResults);
+
+ while (scrollableResultsIterator.hasNext()) {
+ targets.add(scrollableResultsIterator.next());
+ }
+
+ ourLastResultsFromTranslationCache = false; // For testing.
+ myTranslationCache.get(translationQuery, k -> targets);
+ retVal.addAll(targets);
+ } else {
+ ourLastResultsFromTranslationCache = true; // For testing.
+ retVal.addAll(cachedTargets);
+ }
+ }
+
+ return retVal;
+ }
+
+ @Override
+ public List translateWithReverse(TranslationRequest theTranslationRequest) {
+ List retVal = new ArrayList<>();
+
+ CriteriaBuilder criteriaBuilder = myEntityManager.getCriteriaBuilder();
+ CriteriaQuery query = criteriaBuilder.createQuery(TermConceptMapGroupElement.class);
+ Root root = query.from(TermConceptMapGroupElement.class);
+
+ Join targetJoin = root.join("myConceptMapGroupElementTargets");
+ Join groupJoin = root.join("myConceptMapGroup");
+ Join conceptMapJoin = groupJoin.join("myConceptMap");
+
+ List translationQueries = theTranslationRequest.getTranslationQueries();
+ List cachedElements;
+ ArrayList predicates;
+ Coding coding;
+ for (TranslationQuery translationQuery : translationQueries) {
+ cachedElements = myTranslationWithReverseCache.getIfPresent(translationQuery);
+ if (cachedElements == null) {
+ final List elements = new ArrayList<>();
+
+ predicates = new ArrayList<>();
+
+ coding = translationQuery.getCoding();
+ if (coding.hasCode()) {
+ predicates.add(criteriaBuilder.equal(targetJoin.get("myCode"), coding.getCode()));
+ } else {
+ throw new InvalidRequestException("A code must be provided for translation to occur.");
+ }
+
+ if (coding.hasSystem()) {
+ predicates.add(criteriaBuilder.equal(groupJoin.get("myTarget"), coding.getSystem()));
+ }
+
+ if (coding.hasVersion()) {
+ predicates.add(criteriaBuilder.equal(groupJoin.get("myTargetVersion"), coding.getVersion()));
+ }
+
+ if (translationQuery.hasTargetSystem()) {
+ predicates.add(criteriaBuilder.equal(groupJoin.get("mySource"), translationQuery.getTargetSystem().getValueAsString()));
+ }
+
+ if (translationQuery.hasSource()) {
+ predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myTarget"), translationQuery.getSource().getValueAsString()));
+ }
+
+ if (translationQuery.hasTarget()) {
+ predicates.add(criteriaBuilder.equal(conceptMapJoin.get("mySource"), translationQuery.getTarget().getValueAsString()));
+ }
+
+ if (translationQuery.hasResourceId()) {
+ predicates.add(criteriaBuilder.equal(conceptMapJoin.get("myResourcePid"), translationQuery.getResourceId()));
+ }
+
+ Predicate outerPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[0]));
+ query.where(outerPredicate);
+
+ // Use scrollable results.
+ final TypedQuery typedQuery = myEntityManager.createQuery(query.select(root));
+ org.hibernate.query.Query hibernateQuery = (org.hibernate.query.Query) typedQuery;
+ hibernateQuery.setFetchSize(myFetchSize);
+ ScrollableResults scrollableResults = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
+ Iterator scrollableResultsIterator = new ScrollableResultsIterator<>(scrollableResults);
+
+ while (scrollableResultsIterator.hasNext()) {
+ elements.add(scrollableResultsIterator.next());
+ }
+
+ ourLastResultsFromTranslationWithReverseCache = false; // For testing.
+ myTranslationWithReverseCache.get(translationQuery, k -> elements);
+ retVal.addAll(elements);
+ } else {
+ ourLastResultsFromTranslationWithReverseCache = true; // For testing.
+ retVal.addAll(cachedElements);
+ }
+ }
+
+ return retVal;
+ }
+
private int validateConceptForStorage(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, ArrayList theConceptsStack,
IdentityHashMap theAllConcepts) {
ValidateUtil.isTrueOrThrowInvalidRequest(theConcept.getCodeSystemVersion() != null, "CodesystemValue is null");
@@ -921,6 +1233,54 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
}
}
+ /**
+ * This method is present only for unit tests, do not call from client code
+ */
+ @VisibleForTesting
+ static void clearOurLastResultsFromTranslationCache() {
+ ourLastResultsFromTranslationCache = false;
+ }
+
+ /**
+ * This method is present only for unit tests, do not call from client code
+ */
+ @VisibleForTesting
+ static void clearOurLastResultsFromTranslationWithReverseCache() {
+ ourLastResultsFromTranslationWithReverseCache = false;
+ }
+
+ /**
+ * This method is present only for unit tests, do not call from client code
+ */
+ @VisibleForTesting
+ void clearTranslationCache() {
+ myTranslationCache.invalidateAll();
+ }
+
+ /**
+ * This method is present only for unit tests, do not call from client code
+ */
+ @VisibleForTesting()
+ void clearTranslationWithReverseCache() {
+ myTranslationWithReverseCache.invalidateAll();
+ }
+
+ /**
+ * This method is present only for unit tests, do not call from client code
+ */
+ @VisibleForTesting
+ static boolean isOurLastResultsFromTranslationCache() {
+ return ourLastResultsFromTranslationCache;
+ }
+
+ /**
+ * This method is present only for unit tests, do not call from client code
+ */
+ @VisibleForTesting
+ static boolean isOurLastResultsFromTranslationWithReverseCache() {
+ return ourLastResultsFromTranslationWithReverseCache;
+ }
+
/**
* This method is present only for unit tests, do not call from client code
*/
@@ -928,6 +1288,4 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
public static void setForceSaveDeferredAlwaysForUnitTest(boolean theForceSaveDeferredAlwaysForUnitTest) {
ourForceSaveDeferredAlwaysForUnitTest = theForceSaveDeferredAlwaysForUnitTest;
}
-
-
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java
index d19a864aa2f..14009ee6281 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/HapiTerminologySvcDstu3.java
@@ -40,9 +40,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-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvc.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvc.java
index 35f0b13a34e..dbe52226f78 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvc.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/IHapiTerminologySvc.java
@@ -1,10 +1,9 @@
package ca.uhn.fhir.jpa.term;
-import ca.uhn.fhir.jpa.entity.TermCodeSystem;
-import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
-import ca.uhn.fhir.jpa.entity.TermConcept;
+import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ValueSet;
import java.util.List;
@@ -69,6 +68,11 @@ public interface IHapiTerminologySvc {
*/
IIdType storeNewCodeSystemVersion(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequestDetails, List theValueSets, List theConceptMaps);
+ void storeTermConceptMapAndChildren(ResourceTable theResourceTable, ConceptMap theConceptMap);
+
boolean supportsSystem(String theCodeSystem);
+ List translate(TranslationRequest theTranslationRequest);
+
+ List translateWithReverse(TranslationRequest theTranslationRequest);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationMatch.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationMatch.java
new file mode 100644
index 00000000000..7c1ae2f4048
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationMatch.java
@@ -0,0 +1,74 @@
+package ca.uhn.fhir.jpa.term;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.hl7.fhir.r4.model.CodeType;
+import org.hl7.fhir.r4.model.Coding;
+import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
+import org.hl7.fhir.r4.model.UriType;
+
+public class TranslationMatch {
+ private Coding myConcept;
+ private CodeType myEquivalence;
+ private UriType mySource;
+
+ public TranslationMatch() {
+ super();
+ }
+
+ public Coding getConcept() {
+ return myConcept;
+ }
+
+ public void setConcept(Coding theConcept) {
+ myConcept = theConcept;
+ }
+
+ public CodeType getEquivalence() {
+ return myEquivalence;
+ }
+
+ public void setEquivalence(CodeType theEquivalence) {
+ myEquivalence = theEquivalence;
+ }
+
+ public UriType getSource() {
+ return mySource;
+ }
+
+ public void setSource(UriType theSource) {
+ mySource = theSource;
+ }
+
+ public void toParameterParts(ParametersParameterComponent theParam) {
+ if (myEquivalence != null) {
+ theParam.addPart().setName("equivalence").setValue(myEquivalence);
+ }
+
+ if (myConcept != null) {
+ theParam.addPart().setName("concept").setValue(myConcept);
+ }
+
+ if (mySource != null) {
+ theParam.addPart().setName("source").setValue(mySource);
+ }
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationQuery.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationQuery.java
new file mode 100644
index 00000000000..4cd18d09ed5
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationQuery.java
@@ -0,0 +1,128 @@
+package ca.uhn.fhir.jpa.term;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.hl7.fhir.r4.model.Coding;
+import org.hl7.fhir.r4.model.UriType;
+
+public class TranslationQuery {
+ private Coding myCoding;
+ private Long myResourceId;
+ private UriType mySource;
+ private UriType myTarget;
+ private UriType myTargetSystem;
+
+ public TranslationQuery() {
+ super();
+
+ myCoding = new Coding();
+ }
+
+ public Coding getCoding() {
+ return myCoding;
+ }
+
+ public void setCoding(Coding theCoding) {
+ myCoding = theCoding;
+ }
+
+ public boolean hasResourceId() {
+ return myResourceId != null;
+ }
+
+ public Long getResourceId() {
+ return myResourceId;
+ }
+
+ public void setResourceId(Long theResourceId) {
+ myResourceId = theResourceId;
+ }
+
+ public boolean hasSource() {
+ return mySource != null && mySource.hasValue();
+ }
+
+ public UriType getSource() {
+ return mySource;
+ }
+
+ public void setSource(UriType theSource) {
+ mySource = theSource;
+ }
+
+ public boolean hasTarget() {
+ return myTarget != null && myTarget.hasValue();
+ }
+
+ public UriType getTarget() {
+ return myTarget;
+ }
+
+ public void setTarget(UriType theTarget) {
+ myTarget = theTarget;
+ }
+
+ public boolean hasTargetSystem() {
+ return myTargetSystem != null && myTargetSystem.hasValue();
+ }
+
+ public UriType getTargetSystem() {
+ return myTargetSystem;
+ }
+
+ public void setTargetSystem(UriType theTargetSystem) {
+ myTargetSystem = theTargetSystem;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+
+ if (!(o instanceof TranslationQuery)) return false;
+
+ TranslationQuery that = (TranslationQuery) o;
+
+ return new EqualsBuilder()
+ .append(getCoding().getCode(), that.getCoding().getCode())
+ .append(getCoding().getSystem(), that.getCoding().getSystem())
+ .append(getCoding().getVersion(), that.getCoding().getVersion())
+ .append(getResourceId(), that.getResourceId())
+ .append(getSource(), that.getSource())
+ .append(getTarget(), that.getTarget())
+ .append(getTargetSystem(), that.getTargetSystem())
+ .isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37)
+ .append(getCoding().getCode())
+ .append(getCoding().getSystem())
+ .append(getCoding().getVersion())
+ .append(getResourceId())
+ .append(getSource())
+ .append(getTarget())
+ .append(getTargetSystem())
+ .toHashCode();
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationRequest.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationRequest.java
new file mode 100644
index 00000000000..339463ec9a9
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationRequest.java
@@ -0,0 +1,155 @@
+package ca.uhn.fhir.jpa.term;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.hl7.fhir.r4.model.BooleanType;
+import org.hl7.fhir.r4.model.CodeableConcept;
+import org.hl7.fhir.r4.model.Coding;
+import org.hl7.fhir.r4.model.UriType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TranslationRequest {
+ private CodeableConcept myCodeableConcept;
+ private Long myResourceId;
+ private BooleanType myReverse;
+ private UriType mySource;
+ private UriType myTarget;
+ private UriType myTargetSystem;
+
+ public TranslationRequest() {
+ super();
+
+ myCodeableConcept = new CodeableConcept();
+ }
+
+ public CodeableConcept getCodeableConcept() {
+ return myCodeableConcept;
+ }
+
+ public void setCodeableConcept(CodeableConcept theCodeableConcept) {
+ myCodeableConcept = theCodeableConcept;
+ }
+
+ public boolean hasResourceId() {
+ return myResourceId != null;
+ }
+
+ public Long getResourceId() {
+ return myResourceId;
+ }
+
+ public void setResourceId(Long theResourceId) {
+ myResourceId = theResourceId;
+ }
+
+ public boolean hasReverse() {
+ return myReverse != null;
+ }
+
+ public BooleanType getReverse() {
+ return myReverse;
+ }
+
+ public boolean getReverseAsBoolean() {
+ if (hasReverse()) {
+ return myReverse.booleanValue();
+ }
+
+ return false;
+ }
+
+ public void setReverse(BooleanType theReverse) {
+ myReverse = theReverse;
+ }
+
+ public void setReverse(boolean theReverse) {
+ myReverse = new BooleanType(theReverse);
+ }
+
+ public boolean hasSource() {
+ return mySource != null && mySource.hasValue();
+ }
+
+ public UriType getSource() {
+ return mySource;
+ }
+
+ public void setSource(UriType theSource) {
+ mySource = theSource;
+ }
+
+ public boolean hasTarget() {
+ return myTarget != null && myTarget.hasValue();
+ }
+
+ public UriType getTarget() {
+ return myTarget;
+ }
+
+ public void setTarget(UriType theTarget) {
+ myTarget = theTarget;
+ }
+
+ public boolean hasTargetSystem() {
+ return myTargetSystem != null && myTargetSystem.hasValue();
+ }
+
+ public UriType getTargetSystem() {
+ return myTargetSystem;
+ }
+
+ public void setTargetSystem(UriType theTargetSystem) {
+ myTargetSystem = theTargetSystem;
+ }
+
+ public List getTranslationQueries() {
+ List retVal = new ArrayList<>();
+
+ TranslationQuery translationQuery;
+ for (Coding coding : getCodeableConcept().getCoding()) {
+ translationQuery = new TranslationQuery();
+
+ translationQuery.setCoding(coding);
+
+ if (this.hasResourceId()) {
+ translationQuery.setResourceId(this.getResourceId());
+ }
+
+ if (this.hasSource()) {
+ translationQuery.setSource(this.getSource());
+ }
+
+ if (this.hasTarget()) {
+ translationQuery.setTarget(this.getTarget());
+ }
+
+ if (this.hasTargetSystem()) {
+ translationQuery.setTargetSystem(this.getTargetSystem());
+ }
+
+ retVal.add(translationQuery);
+ }
+
+ return retVal;
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationResult.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationResult.java
new file mode 100644
index 00000000000..edd8487055e
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/TranslationResult.java
@@ -0,0 +1,88 @@
+package ca.uhn.fhir.jpa.term;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.hl7.fhir.r4.model.BooleanType;
+import org.hl7.fhir.r4.model.Parameters;
+import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
+import org.hl7.fhir.r4.model.StringType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TranslationResult {
+ private List myMatches;
+ private StringType myMessage;
+ private BooleanType myResult;
+
+ public TranslationResult() {
+ super();
+
+ myMatches = new ArrayList<>();
+ }
+
+ public List getMatches() {
+ return myMatches;
+ }
+
+ public void setMatches(List theMatches) {
+ myMatches = theMatches;
+ }
+
+ public boolean addMatch(TranslationMatch theMatch) {
+ return myMatches.add(theMatch);
+ }
+
+ public StringType getMessage() {
+ return myMessage;
+ }
+
+ public void setMessage(StringType theMessage) {
+ myMessage = theMessage;
+ }
+
+ public BooleanType getResult() {
+ return myResult;
+ }
+
+ public void setResult(BooleanType theMatched) {
+ myResult = theMatched;
+ }
+
+ public Parameters toParameters() {
+ Parameters retVal = new Parameters();
+
+ if (myResult != null) {
+ retVal.addParameter().setName("result").setValue(myResult);
+ }
+
+ if (myMessage != null) {
+ retVal.addParameter().setName("message").setValue(myMessage);
+ }
+
+ for (TranslationMatch translationMatch : myMatches) {
+ ParametersParameterComponent matchParam = retVal.addParameter().setName("match");
+ translationMatch.toParameterParts(matchParam);
+ }
+
+ return retVal;
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/JpaConstants.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/JpaConstants.java
index dd80d0b63e5..86ad478627a 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/JpaConstants.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/JpaConstants.java
@@ -160,4 +160,8 @@ public class JpaConstants {
*/
public static final String OPERATION_META_ADD = "$meta-add";
+ /**
+ * Operation name for the $translate operation
+ */
+ public static final String OPERATION_TRANSLATE = "$translate";
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/ScrollableResultsIterator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/ScrollableResultsIterator.java
new file mode 100644
index 00000000000..58b6bcec10f
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/ScrollableResultsIterator.java
@@ -0,0 +1,63 @@
+package ca.uhn.fhir.jpa.util;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2018 University Health Network
+ * %%
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.apache.commons.lang3.Validate;
+import org.hibernate.ScrollableResults;
+
+import java.util.Iterator;
+
+public class ScrollableResultsIterator extends BaseIterator implements Iterator {
+ private boolean hasNext;
+ private T myNext;
+ private ScrollableResults myScroll;
+
+ public ScrollableResultsIterator(ScrollableResults theScroll) {
+ myScroll = theScroll;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void ensureHaveNext() {
+ if (myNext == null) {
+ if (myScroll.next()) {
+ hasNext = true;
+ myNext = (T) myScroll.get(0);
+ } else {
+ hasNext = false;
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ ensureHaveNext();
+ return hasNext;
+ }
+
+ @Override
+ public T next() {
+ ensureHaveNext();
+ Validate.isTrue(hasNext);
+ T next = myNext;
+ myNext = null;
+ return next;
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
index bf776616241..fbaa522e788 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java
@@ -49,6 +49,15 @@ import static org.mockito.Mockito.when;
public abstract class BaseJpaTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaTest.class);
+
+ protected static final String CM_URL = "http://example.com/my_concept_map";
+ protected static final String CS_URL = "http://example.com/my_code_system";
+ protected static final String CS_URL_2 = "http://example.com/my_code_system2";
+ protected static final String CS_URL_3 = "http://example.com/my_code_system3";
+ protected static final String CS_URL_4 = "http://example.com/my_code_system4";
+ protected static final String VS_URL = "http://example.com/my_value_set";
+ protected static final String VS_URL_2 = "http://example.com/my_value_set2";
+
protected ServletRequestDetails mySrd;
protected ArrayList myServerInterceptorList;
protected IRequestOperationCallback myRequestOperationCallback = mock(IRequestOperationCallback.class);
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java
index 1c0a43d4381..849ba5ce391 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java
@@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.config.TestDstu3Config;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
+import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
@@ -14,20 +15,22 @@ import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.util.ResourceCountCache;
-import ca.uhn.fhir.jpa.util.SingleItemLoadingCache;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainDstu3;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.io.IOUtils;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;
+import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.After;
import org.junit.AfterClass;
@@ -48,7 +51,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
-import static org.junit.Assert.*;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
@RunWith(SpringJUnit4ClassRunner.class)
@@ -91,7 +94,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
protected IFhirResourceDao myCompartmentDefinitionDao;
@Autowired
@Qualifier("myConceptMapDaoDstu3")
- protected IFhirResourceDao myConceptMapDao;
+ protected IFhirResourceDaoConceptMap myConceptMapDao;
@Autowired
@Qualifier("myConditionDaoDstu3")
protected IFhirResourceDao myConditionDao;
@@ -229,6 +232,10 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
protected IFhirResourceDaoValueSet myValueSetDao;
@Autowired
private JpaValidationSupportChainDstu3 myJpaValidationSupportChainDstu3;
+ @Autowired
+ protected ITermConceptMapDao myTermConceptMapDao;
+ @Autowired
+ protected ITermConceptMapGroupElementTargetDao myTermConceptMapGroupElementTargetDao;
@After()
public void afterCleanupDao() {
@@ -315,4 +322,34 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
return uuid;
}
+ /**
+ * Creates a single {@link org.hl7.fhir.dstu3.model.ConceptMap} entity that includes:
+ *
+ *
+ * -
+ * One group with two elements, each identifying one target apiece.
+ *
+ * -
+ * One group with one element, identifying two targets.
+ *
+ * -
+ * One group with one element, identifying a target that also appears
+ * in the first element of the first group.
+ *
+ *
+ *
+ * The first two groups identify the same source code system and different target code systems.
+ *
+ * The first two groups also include an element with the same source code.
+ *
+ *
+ * @return A {@link org.hl7.fhir.dstu3.model.ConceptMap} entity for testing.
+ */
+ public static ConceptMap createConceptMap() {
+ try {
+ return VersionConvertor_30_40.convertConceptMap(BaseJpaR4Test.createConceptMap());
+ } catch (FHIRException fe) {
+ throw new InternalErrorException(fe);
+ }
+ }
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ConceptMapTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ConceptMapTest.java
new file mode 100644
index 00000000000..62a41cde417
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ConceptMapTest.java
@@ -0,0 +1,84 @@
+package ca.uhn.fhir.jpa.dao.dstu3;
+
+import ca.uhn.fhir.jpa.term.TranslationMatch;
+import ca.uhn.fhir.jpa.term.TranslationRequest;
+import ca.uhn.fhir.jpa.term.TranslationResult;
+import ca.uhn.fhir.util.TestUtil;
+import org.hl7.fhir.dstu3.model.ConceptMap;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.Coding;
+import org.hl7.fhir.r4.model.Enumerations;
+import org.hl7.fhir.r4.model.UriType;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import static org.junit.Assert.*;
+
+public class FhirResourceDaoDstu3ConceptMapTest extends BaseJpaDstu3Test {
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3ConceptMapTest.class);
+
+ private IIdType myConceptMapId;
+
+ @AfterClass
+ public static void afterClassClearContext() {
+ TestUtil.clearAllStaticFieldsForUnitTest();
+ }
+
+ @Before
+ @Transactional
+ public void before02() {
+ myConceptMapId = myConceptMapDao.create(createConceptMap(), mySrd).getId().toUnqualifiedVersionless();
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToMany() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_3));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(Enumerations.ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(Enumerations.ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ //
+ }
+ });
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
index 8e8c44ba9b2..0e0f4f48c56 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/BaseJpaR4Test.java
@@ -29,6 +29,10 @@ import org.hibernate.search.jpa.Search;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r4.model.*;
+import org.hl7.fhir.r4.model.ConceptMap.ConceptMapGroupComponent;
+import org.hl7.fhir.r4.model.ConceptMap.SourceElementComponent;
+import org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent;
+import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -48,13 +52,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
-import static org.junit.Assert.*;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestR4Config.class})
public abstract class BaseJpaR4Test extends BaseJpaTest {
-
private static JpaValidationSupportChainR4 ourJpaValidationSupportChainR4;
private static IFhirResourceDaoValueSet ourValueSetDao;
@@ -102,7 +105,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
protected IFhirResourceDao myCompartmentDefinitionDao;
@Autowired
@Qualifier("myConceptMapDaoR4")
- protected IFhirResourceDao myConceptMapDao;
+ protected IFhirResourceDaoConceptMap myConceptMapDao;
@Autowired
@Qualifier("myConditionDaoR4")
protected IFhirResourceDao myConditionDao;
@@ -240,6 +243,10 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
protected IFhirResourceDaoValueSet myValueSetDao;
@Autowired
private JpaValidationSupportChainR4 myJpaValidationSupportChainR4;
+ @Autowired
+ protected ITermConceptMapDao myTermConceptMapDao;
+ @Autowired
+ protected ITermConceptMapGroupElementTargetDao myTermConceptMapGroupElementTargetDao;
@After()
public void afterCleanupDao() {
@@ -327,4 +334,141 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
return uuid;
}
+ /**
+ * Creates a single {@link org.hl7.fhir.r4.model.ConceptMap} entity that includes:
+ *
+ *
+ * -
+ * One group with two elements, each identifying one target apiece.
+ *
+ * -
+ * One group with one element, identifying two targets.
+ *
+ * -
+ * One group with one element, identifying a target that also appears
+ * in the first element of the first group.
+ *
+ *
+ *
+ * The first two groups identify the same source code system and different target code systems.
+ *
+ * The first two groups also include an element with the same source code.
+ *
+ * @return A {@link org.hl7.fhir.r4.model.ConceptMap} entity for testing.
+ */
+ public static ConceptMap createConceptMap() {
+ //
+ ConceptMap conceptMap = new ConceptMap();
+ conceptMap.setUrl(CM_URL);
+
+ conceptMap.setSource(new UriType(VS_URL));
+ conceptMap.setTarget(new UriType(VS_URL_2));
+
+ //
+ ConceptMapGroupComponent group = conceptMap.addGroup();
+ group.setSource(CS_URL);
+ group.setSourceVersion("Version 1");
+ group.setTarget(CS_URL_2);
+ group.setTargetVersion("Version 2");
+
+ //
+ SourceElementComponent element = group.addElement();
+ element.setCode("12345");
+ element.setDisplay("Source Code 12345");
+
+ //
+ TargetElementComponent target = element.addTarget();
+ target.setCode("34567");
+ target.setDisplay("Target Code 34567");
+ target.setEquivalence(ConceptMapEquivalence.EQUAL);
+ // End ConceptMap.group(0).element(0).target(0)
+ //
+
+ // End ConceptMap.group(0).element(0)
+ //
+
+ //
+ element = group.addElement();
+ element.setCode("23456");
+ element.setDisplay("Source Code 23456");
+
+ //
+ target = element.addTarget();
+ target.setCode("45678");
+ target.setDisplay("Target Code 45678");
+ target.setEquivalence(ConceptMapEquivalence.WIDER);
+ // End ConceptMap.group(0).element(1).target(0)
+ //
+
+ // End ConceptMap.group(0).element(1)
+ //
+
+ // End ConceptMap.group(0)
+ //
+
+ //
+ group = conceptMap.addGroup();
+ group.setSource(CS_URL);
+ group.setSourceVersion("Version 3");
+ group.setTarget(CS_URL_3);
+ group.setTargetVersion("Version 4");
+
+ //
+ element = group.addElement();
+ element.setCode("12345");
+ element.setDisplay("Source Code 12345");
+
+ //
+ target = element.addTarget();
+ target.setCode("56789");
+ target.setDisplay("Target Code 56789");
+ target.setEquivalence(ConceptMapEquivalence.EQUAL);
+ // End ConceptMap.group(1).element(0).target(0)
+ //
+
+ //
+ target = element.addTarget();
+ target.setCode("67890");
+ target.setDisplay("Target Code 67890");
+ target.setEquivalence(ConceptMapEquivalence.WIDER);
+ // End ConceptMap.group(1).element(0).target(1)
+ //
+
+ // End ConceptMap.group(1).element(0)
+ //
+
+ // End ConceptMap.group(1)
+ //
+
+ //
+ group = conceptMap.addGroup();
+ group.setSource(CS_URL_4);
+ group.setSourceVersion("Version 5");
+ group.setTarget(CS_URL_2);
+ group.setTargetVersion("Version 2");
+
+ //
+ element = group.addElement();
+ element.setCode("78901");
+ element.setDisplay("Source Code 78901");
+
+ //
+ target = element.addTarget();
+ target.setCode("34567");
+ target.setDisplay("Target Code 34567");
+ target.setEquivalence(ConceptMapEquivalence.NARROWER);
+ // End ConceptMap.group(2).element(0).target(0)
+ //
+
+ // End ConceptMap.group(2).element(0)
+ //
+
+ // End ConceptMap.group(2)
+ //
+
+ // End ConceptMap
+ //
+
+ return conceptMap;
+ }
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ConceptMapTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ConceptMapTest.java
new file mode 100644
index 00000000000..3a0cd357688
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ConceptMapTest.java
@@ -0,0 +1,980 @@
+package ca.uhn.fhir.jpa.dao.r4;
+
+import ca.uhn.fhir.jpa.term.TranslationMatch;
+import ca.uhn.fhir.jpa.term.TranslationRequest;
+import ca.uhn.fhir.jpa.term.TranslationResult;
+import ca.uhn.fhir.util.TestUtil;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.Coding;
+import org.hl7.fhir.r4.model.ConceptMap;
+import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
+import org.hl7.fhir.r4.model.UriType;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import static org.junit.Assert.*;
+
+public class FhirResourceDaoR4ConceptMapTest extends BaseJpaR4Test {
+ private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4ConceptMapTest.class);
+
+ private IIdType myConceptMapId;
+
+ @AfterClass
+ public static void afterClassClearContext() {
+ TestUtil.clearAllStaticFieldsForUnitTest();
+ }
+
+ @Before
+ @Transactional
+ public void before02() {
+ myConceptMapId = myConceptMapDao.create(createConceptMap(), mySrd).getId().toUnqualifiedVersionless();
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToMany() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_3));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToOne() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_2));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(1, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("34567", concept.getCode());
+ assertEquals("Target Code 34567", concept.getDisplay());
+ assertEquals(CS_URL_2, concept.getSystem());
+ assertEquals("Version 2", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeUnmapped() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("BOGUS");
+ translationRequest.setTargetSystem(new UriType(CS_URL_3));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertFalse(translationResult.getResult().booleanValue());
+ assertEquals("No matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(0, translationResult.getMatches().size());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithCodeOnly() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(3, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("34567", concept.getCode());
+ assertEquals("Target Code 34567", concept.getDisplay());
+ assertEquals(CS_URL_2, concept.getSystem());
+ assertEquals("Version 2", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(2);
+ assertEquals(ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystem() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(3, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("34567", concept.getCode());
+ assertEquals("Target Code 34567", concept.getDisplay());
+ assertEquals(CS_URL_2, concept.getSystem());
+ assertEquals("Version 2", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(2);
+ assertEquals(ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystemAndVersion1() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #1
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345")
+ .setVersion("Version 1");
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(1, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("34567", concept.getCode());
+ assertEquals("Target Code 34567", concept.getDisplay());
+ assertEquals(CS_URL_2, concept.getSystem());
+ assertEquals("Version 2", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystemAndVersion3() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #3
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345")
+ .setVersion("Version 3");
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceAndTargetSystem2() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #2
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_2));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(1, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("34567", concept.getCode());
+ assertEquals("Target Code 34567", concept.getDisplay());
+ assertEquals(CS_URL_2, concept.getSystem());
+ assertEquals("Version 2", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceAndTargetSystem3() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #3
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_3));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source value set
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+ translationRequest.setSource(new UriType(VS_URL));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(3, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("34567", concept.getCode());
+ assertEquals("Target Code 34567", concept.getDisplay());
+ assertEquals(CS_URL_2, concept.getSystem());
+ assertEquals("Version 2", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(2);
+ assertEquals(ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithTargetValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * target value set
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+ translationRequest.setTarget(new UriType(VS_URL_2));
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(3, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("34567", concept.getCode());
+ assertEquals("Target Code 34567", concept.getDisplay());
+ assertEquals(CS_URL_2, concept.getSystem());
+ assertEquals("Version 2", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertEquals(ConceptMapEquivalence.EQUAL.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("56789", concept.getCode());
+ assertEquals("Target Code 56789", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(2);
+ assertEquals(ConceptMapEquivalence.WIDER.toCode(), translationMatch.getEquivalence().getCode());
+ concept = translationMatch.getConcept();
+ assertEquals("67890", concept.getCode());
+ assertEquals("Target Code 67890", concept.getDisplay());
+ assertEquals(CS_URL_3, concept.getSystem());
+ assertEquals("Version 4", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverse() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(new UriType(CS_URL_4));
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(1, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("78901", concept.getCode());
+ assertEquals("Source Code 78901", concept.getDisplay());
+ assertEquals(CS_URL_4, concept.getSystem());
+ assertEquals("Version 5", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseByCodeSystemsAndSourceCodeUnmapped() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_3)
+ .setCode("BOGUS");
+ translationRequest.setTargetSystem(new UriType(CS_URL));
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertFalse(translationResult.getResult().booleanValue());
+ assertEquals("No matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(0, translationResult.getMatches().size());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithCodeOnly() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("12345", concept.getCode());
+ assertEquals("Source Code 12345", concept.getDisplay());
+ assertEquals(CS_URL, concept.getSystem());
+ assertEquals("Version 1", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertNull(translationMatch.getEquivalence());
+ concept = translationMatch.getConcept();
+ assertEquals("78901", concept.getCode());
+ assertEquals("Source Code 78901", concept.getDisplay());
+ assertEquals(CS_URL_4, concept.getSystem());
+ assertEquals("Version 5", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceSystem() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("12345", concept.getCode());
+ assertEquals("Source Code 12345", concept.getDisplay());
+ assertEquals(CS_URL, concept.getSystem());
+ assertEquals("Version 1", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertNull(translationMatch.getEquivalence());
+ concept = translationMatch.getConcept();
+ assertEquals("78901", concept.getCode());
+ assertEquals("Source Code 78901", concept.getDisplay());
+ assertEquals(CS_URL_4, concept.getSystem());
+ assertEquals("Version 5", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceSystemAndVersion() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567")
+ .setVersion("Version 2");
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("12345", concept.getCode());
+ assertEquals("Source Code 12345", concept.getDisplay());
+ assertEquals(CS_URL, concept.getSystem());
+ assertEquals("Version 1", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertNull(translationMatch.getEquivalence());
+ concept = translationMatch.getConcept();
+ assertEquals("78901", concept.getCode());
+ assertEquals("Source Code 78901", concept.getDisplay());
+ assertEquals(CS_URL_4, concept.getSystem());
+ assertEquals("Version 5", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem1() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #1
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(new UriType(CS_URL));
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(1, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("12345", concept.getCode());
+ assertEquals("Source Code 12345", concept.getDisplay());
+ assertEquals(CS_URL, concept.getSystem());
+ assertEquals("Version 1", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem4() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #4
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(new UriType(CS_URL_4));
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(1, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("78901", concept.getCode());
+ assertEquals("Source Code 78901", concept.getDisplay());
+ assertEquals(CS_URL_4, concept.getSystem());
+ assertEquals("Version 5", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source value set
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setSource(new UriType(VS_URL_2));
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("12345", concept.getCode());
+ assertEquals("Source Code 12345", concept.getDisplay());
+ assertEquals(CS_URL, concept.getSystem());
+ assertEquals("Version 1", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertNull(translationMatch.getEquivalence());
+ concept = translationMatch.getConcept();
+ assertEquals("78901", concept.getCode());
+ assertEquals("Source Code 78901", concept.getDisplay());
+ assertEquals(CS_URL_4, concept.getSystem());
+ assertEquals("Version 5", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithTargetValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * target value set
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setTarget(new UriType(VS_URL));
+ translationRequest.setReverse(true);
+
+ TranslationResult translationResult = myConceptMapDao.translate(translationRequest, null);
+
+ assertTrue(translationResult.getResult().booleanValue());
+ assertEquals("Matches found!", translationResult.getMessage().getValueAsString());
+
+ assertEquals(2, translationResult.getMatches().size());
+
+ TranslationMatch translationMatch = translationResult.getMatches().get(0);
+ assertNull(translationMatch.getEquivalence());
+ Coding concept = translationMatch.getConcept();
+ assertEquals("12345", concept.getCode());
+ assertEquals("Source Code 12345", concept.getDisplay());
+ assertEquals(CS_URL, concept.getSystem());
+ assertEquals("Version 1", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+
+ translationMatch = translationResult.getMatches().get(1);
+ assertNull(translationMatch.getEquivalence());
+ concept = translationMatch.getConcept();
+ assertEquals("78901", concept.getCode());
+ assertEquals("Source Code 78901", concept.getDisplay());
+ assertEquals(CS_URL_4, concept.getSystem());
+ assertEquals("Version 5", concept.getVersion());
+ assertFalse(concept.getUserSelected());
+ assertEquals(CM_URL, translationMatch.getSource().getValueAsString());
+ }
+ });
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/BaseResourceProviderDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/BaseResourceProviderDstu3Test.java
index e2c29d85153..a66c7d9afda 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/BaseResourceProviderDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/BaseResourceProviderDstu3Test.java
@@ -26,6 +26,8 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
+import org.hl7.fhir.dstu3.model.Parameters;
+import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.dstu3.model.Patient;
import org.junit.After;
import org.junit.AfterClass;
@@ -201,4 +203,56 @@ public abstract class BaseResourceProviderDstu3Test extends BaseJpaDstu3Test {
TestUtil.clearAllStaticFieldsForUnitTest();
}
+ public static int getNumberOfParametersByName(Parameters theParameters, String theName) {
+ int retVal = 0;
+
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ retVal++;
+ }
+ }
+
+ return retVal;
+ }
+
+ public static ParametersParameterComponent getParameterByName(Parameters theParameters, String theName) {
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ return param;
+ }
+ }
+
+ return new ParametersParameterComponent();
+ }
+
+ public static List getParametersByName(Parameters theParameters, String theName) {
+ List params = new ArrayList<>();
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ params.add(param);
+ }
+ }
+
+ return params;
+ }
+
+ public static ParametersParameterComponent getPartByName(ParametersParameterComponent theParameter, String theName) {
+ for (ParametersParameterComponent part : theParameter.getPart()) {
+ if (part.getName().equals(theName)) {
+ return part;
+ }
+ }
+
+ return new ParametersParameterComponent();
+ }
+
+ public static boolean hasParameterByName(Parameters theParameters, String theName) {
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3ConceptMapTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3ConceptMapTest.java
new file mode 100644
index 00000000000..9d12b26e56c
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderDstu3ConceptMapTest.java
@@ -0,0 +1,89 @@
+package ca.uhn.fhir.jpa.provider.dstu3;
+
+import ca.uhn.fhir.util.TestUtil;
+import org.hl7.fhir.dstu3.model.*;
+import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+public class ResourceProviderDstu3ConceptMapTest extends BaseResourceProviderDstu3Test {
+ private static final Logger ourLog = LoggerFactory.getLogger(ResourceProviderDstu3ConceptMapTest.class);
+
+ private IIdType myConceptMapId;
+
+ @AfterClass
+ public static void afterClassClearContext() {
+ TestUtil.clearAllStaticFieldsForUnitTest();
+ }
+
+ @Before
+ @Transactional
+ public void before02() {
+ myConceptMapId = myConceptMapDao.create(createConceptMap(), mySrd).getId().toUnqualifiedVersionless();
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToMany() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = ourClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getValueAsString());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getValueAsString());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java
index d4eaa6482fc..91c5aba4e89 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/BaseResourceProviderR4Test.java
@@ -27,6 +27,8 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
+import org.hl7.fhir.r4.model.Parameters;
+import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r4.model.Patient;
import org.junit.After;
import org.junit.AfterClass;
@@ -215,4 +217,56 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test {
TestUtil.clearAllStaticFieldsForUnitTest();
}
+ public static int getNumberOfParametersByName(Parameters theParameters, String theName) {
+ int retVal = 0;
+
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ retVal++;
+ }
+ }
+
+ return retVal;
+ }
+
+ public static ParametersParameterComponent getParameterByName(Parameters theParameters, String theName) {
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ return param;
+ }
+ }
+
+ return new ParametersParameterComponent();
+ }
+
+ public static List getParametersByName(Parameters theParameters, String theName) {
+ List params = new ArrayList<>();
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ params.add(param);
+ }
+ }
+
+ return params;
+ }
+
+ public static ParametersParameterComponent getPartByName(ParametersParameterComponent theParameter, String theName) {
+ for (ParametersParameterComponent part : theParameter.getPart()) {
+ if (part.getName().equals(theName)) {
+ return part;
+ }
+ }
+
+ return new ParametersParameterComponent();
+ }
+
+ public static boolean hasParameterByName(Parameters theParameters, String theName) {
+ for (ParametersParameterComponent param : theParameters.getParameter()) {
+ if (param.getName().equals(theName)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ConceptMapTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ConceptMapTest.java
new file mode 100644
index 00000000000..cc455dedaea
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4ConceptMapTest.java
@@ -0,0 +1,1657 @@
+package ca.uhn.fhir.jpa.provider.r4;
+
+import ca.uhn.fhir.util.TestUtil;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.*;
+import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+public class ResourceProviderR4ConceptMapTest extends BaseResourceProviderR4Test {
+ private static final Logger ourLog = LoggerFactory.getLogger(ResourceProviderR4ConceptMapTest.class);
+
+ private IIdType myConceptMapId;
+
+ @AfterClass
+ public static void afterClassClearContext() {
+ TestUtil.clearAllStaticFieldsForUnitTest();
+ }
+
+ @Before
+ @Transactional
+ public void before02() {
+ myConceptMapId = myConceptMapDao.create(createConceptMap(), mySrd).getId().toUnqualifiedVersionless();
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToMany() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToOne() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParameterByName(respParams, "match");
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeUnmapped() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
+ inParams.addParameter().setName("code").setValue(new CodeType("BOGUS"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertFalse(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("No matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertFalse(hasParameterByName(respParams, "match"));
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithCodeOnly() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(3, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(2);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesCoding() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #1
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("coding").setValue(
+ new Coding().setSystem(CS_URL).setCode("12345").setVersion("Version 1"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParameterByName(respParams, "match");
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithCodeableConcept() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system versions #1 and #3
+ */
+ CodeableConcept codeableConcept = new CodeableConcept();
+ codeableConcept.addCoding(new Coding().setSystem(CS_URL).setCode("12345").setVersion("Version 1"));
+ codeableConcept.addCoding(new Coding().setSystem(CS_URL).setCode("23456").setVersion("Version 1"));
+ codeableConcept.addCoding(new Coding().setSystem(CS_URL).setCode("12345").setVersion("Version 3"));
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("codeableConcept").setValue(codeableConcept);
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(4, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("45678", coding.getCode());
+ assertEquals("Target Code 45678", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(2);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(3);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystem() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(3, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(2);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystemAndVersion1() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #1
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("version").setValue(new StringType("Version 1"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParameterByName(respParams, "match");
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystemAndVersion3() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #3
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("version").setValue(new StringType("Version 3"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceAndTargetSystem2() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #2
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_2));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParameterByName(respParams, "match");
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceAndTargetSystem3() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #3
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_3));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source value set
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+ inParams.addParameter().setName("source").setValue(new UriType(VS_URL));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(3, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(2);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithTargetValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * target value set
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+ inParams.addParameter().setName("target").setValue(new UriType(VS_URL_2));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(3, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(2);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithInstance() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("12345"));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onInstance(myConceptMapId)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(3, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(3, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("34567", coding.getCode());
+ assertEquals("Target Code 34567", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_2, coding.getSystem());
+ assertEquals("Version 2", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("equal", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("56789", coding.getCode());
+ assertEquals("Target Code 56789", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(2);
+ assertEquals(3, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertEquals("wider", ((CodeType) part.getValue()).getCode());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("67890", coding.getCode());
+ assertEquals("Target Code 67890", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_3, coding.getSystem());
+ assertEquals("Version 4", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverse() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_2));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_4));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseByCodeSystemsAndSourceCodeUnmapped() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_3));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("code").setValue(new CodeType("BOGUS"));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertFalse(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("No matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertFalse(hasParameterByName(respParams, "match"));
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithCodeOnly() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesCoding() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("coding").setValue(
+ new Coding().setSystem(CS_URL_2).setCode("34567").setVersion("Version 2"));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithCodeableConcept() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version
+ * reverse = true
+ */
+ CodeableConcept codeableConcept = new CodeableConcept();
+ codeableConcept.addCoding(new Coding().setSystem(CS_URL_2).setCode("34567").setVersion("Version 2"));
+ codeableConcept.addCoding(new Coding().setSystem(CS_URL_2).setCode("45678").setVersion("Version 2"));
+ codeableConcept.addCoding(new Coding().setSystem(CS_URL_3).setCode("56789").setVersion("Version 4"));
+ codeableConcept.addCoding(new Coding().setSystem(CS_URL_3).setCode("67890").setVersion("Version 4"));
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("codeableConcept").setValue(codeableConcept);
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(4, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(2);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("23456", coding.getCode());
+ assertEquals("Source Code 23456", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(3);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 3", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceSystem() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_2));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceSystemAndVersion() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_2));
+ inParams.addParameter().setName("version").setValue(new StringType("Version 2"));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem1() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #1
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_2));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem4() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #4
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("system").setValue(new UriType(CS_URL_2));
+ inParams.addParameter().setName("targetsystem").setValue(new UriType(CS_URL_4));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(1, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * source value set
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("source").setValue(new UriType(VS_URL_2));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithTargetValueSet() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ /*
+ * Provided:
+ * source code
+ * target value set
+ * reverse = true
+ */
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("target").setValue(new UriType(VS_URL));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onType(ConceptMap.class)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+
+ @Test
+ public void testTranslateWithReverseAndInstance() {
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ Parameters inParams = new Parameters();
+ inParams.addParameter().setName("code").setValue(new CodeType("34567"));
+ inParams.addParameter().setName("reverse").setValue(new BooleanType(true));
+
+ ourLog.info("Request Parameters:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(inParams));
+
+ Parameters respParams = myClient
+ .operation()
+ .onInstance(myConceptMapId)
+ .named("translate")
+ .withParameters(inParams)
+ .execute();
+
+ ourLog.info("Response Parameters\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParams));
+
+ ParametersParameterComponent param = getParameterByName(respParams, "result");
+ assertTrue(((BooleanType) param.getValue()).booleanValue());
+
+ param = getParameterByName(respParams, "message");
+ assertEquals("Matches found!", ((StringType) param.getValue()).getValueAsString());
+
+ assertEquals(2, getNumberOfParametersByName(respParams, "match"));
+
+ param = getParametersByName(respParams, "match").get(0);
+ assertEquals(2, param.getPart().size());
+ ParametersParameterComponent part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ Coding coding = (Coding) part.getValue();
+ assertEquals("12345", coding.getCode());
+ assertEquals("Source Code 12345", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL, coding.getSystem());
+ assertEquals("Version 1", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+
+ param = getParametersByName(respParams, "match").get(1);
+ assertEquals(2, param.getPart().size());
+ part = getPartByName(param, "equivalence");
+ assertFalse(part.hasValue());
+ part = getPartByName(param, "concept");
+ coding = (Coding) part.getValue();
+ assertEquals("78901", coding.getCode());
+ assertEquals("Source Code 78901", coding.getDisplay());
+ assertFalse(coding.getUserSelected());
+ assertEquals(CS_URL_4, coding.getSystem());
+ assertEquals("Version 5", coding.getVersion());
+ part = getPartByName(param, "source");
+ assertEquals(CM_URL, ((UriType) part.getValue()).getValueAsString());
+ }
+}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java
index 0b0214562b2..209ed2dd840 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplDstu3Test.java
@@ -430,5 +430,4 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
-
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplR4Test.java
new file mode 100644
index 00000000000..8c542f726e6
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/TerminologySvcImplR4Test.java
@@ -0,0 +1,1401 @@
+package ca.uhn.fhir.jpa.term;
+
+import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
+import ca.uhn.fhir.jpa.entity.TermConceptMap;
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroup;
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
+import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
+import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
+import ca.uhn.fhir.util.TestUtil;
+import org.hl7.fhir.instance.model.api.IIdType;
+import org.hl7.fhir.r4.model.ConceptMap;
+import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
+import org.hl7.fhir.r4.model.UriType;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.util.AopTestUtils;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.junit.Assert.*;
+
+public class TerminologySvcImplR4Test extends BaseJpaR4Test {
+ private static final Logger ourLog = LoggerFactory.getLogger(TerminologySvcImplR4Test.class);
+
+ private IIdType myConceptMapId;
+
+ @Rule
+ public final ExpectedException expectedException = ExpectedException.none();
+
+ @AfterClass
+ public static void afterClassClearContext() {
+ TestUtil.clearAllStaticFieldsForUnitTest();
+ }
+
+ @Before
+ public void beforeClearCache() {
+ BaseHapiTerminologySvcImpl baseHapiTerminologySvc = AopTestUtils.getTargetObject(myTermSvc);
+ baseHapiTerminologySvc.clearTranslationCache();
+ BaseHapiTerminologySvcImpl.clearOurLastResultsFromTranslationCache();
+ baseHapiTerminologySvc.clearTranslationWithReverseCache();
+ BaseHapiTerminologySvcImpl.clearOurLastResultsFromTranslationWithReverseCache();
+ }
+
+ private void persistConceptMap() {
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ myConceptMapId = myConceptMapDao.create(createConceptMap(), mySrd).getId().toUnqualifiedVersionless();
+ }
+ });
+ }
+
+ @Test
+ public void testDuplicateConceptMapUrls() {
+ persistConceptMap();
+
+ expectedException.expect(UnprocessableEntityException.class);
+ expectedException.expectMessage("Can not create multiple ConceptMap resources with ConceptMap.url \"http://example.com/my_concept_map\", already have one with resource ID: " + myConceptMapId.getIdPart());
+
+ persistConceptMap();
+ }
+
+ @Test
+ public void testStoreTermConceptMapAndChildren() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ Optional optionalConceptMap = myTermConceptMapDao.findTermConceptMapByUrl(CM_URL);
+ assertTrue(optionalConceptMap.isPresent());
+
+ TermConceptMap conceptMap = optionalConceptMap.get();
+
+ ourLog.info("ConceptMap:\n" + conceptMap.toString());
+
+ assertEquals(VS_URL, conceptMap.getSource());
+ assertEquals(VS_URL_2, conceptMap.getTarget());
+ assertEquals(CM_URL, conceptMap.getUrl());
+ assertEquals(3, conceptMap.getConceptMapGroups().size());
+
+ //
+ TermConceptMapGroup group = conceptMap.getConceptMapGroups().get(0);
+
+ ourLog.info("ConceptMap.group(0):\n" + group.toString());
+
+ assertEquals(CS_URL, group.getSource());
+ assertEquals("Version 1", group.getSourceVersion());
+ assertEquals(VS_URL, group.getSourceValueSet());
+ assertEquals(CS_URL_2, group.getTarget());
+ assertEquals("Version 2", group.getTargetVersion());
+ assertEquals(VS_URL_2, group.getTargetValueSet());
+ assertEquals(CM_URL, group.getConceptMapUrl());
+ assertEquals(2, group.getConceptMapGroupElements().size());
+
+ //
+ TermConceptMapGroupElement element = group.getConceptMapGroupElements().get(0);
+
+ ourLog.info("ConceptMap.group(0).element(0):\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
+
+ //
+ TermConceptMapGroupElementTarget target = element.getConceptMapGroupElementTargets().get(0);
+
+ ourLog.info("ConceptMap.group(0).element(0).target(0):\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+ // End ConceptMap.group(0).element(0).target(0)
+ //
+
+ // End ConceptMap.group(0).element(0)
+ //
+
+ //
+ element = group.getConceptMapGroupElements().get(1);
+
+ ourLog.info("ConceptMap.group(0).element(1):\n" + element.toString());
+
+ assertEquals("23456", element.getCode());
+ assertEquals("Source Code 23456", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
+
+ //
+ target = element.getConceptMapGroupElementTargets().get(0);
+
+ ourLog.info("ConceptMap.group(0).element(1).target(0):\n" + target.toString());
+
+ assertEquals("45678", target.getCode());
+ assertEquals("Target Code 45678", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+ // End ConceptMap.group(0).element(1).target(0)
+ //
+
+ // End ConceptMap.group(0).element(1)
+ //
+
+ // End ConceptMap.group(0)
+ //
+
+ //
+ group = conceptMap.getConceptMapGroups().get(1);
+
+ ourLog.info("ConceptMap.group(1):\n" + group.toString());
+
+ assertEquals(CS_URL, group.getSource());
+ assertEquals("Version 3", group.getSourceVersion());
+ assertEquals(CS_URL_3, group.getTarget());
+ assertEquals("Version 4", group.getTargetVersion());
+ assertEquals(CM_URL, group.getConceptMapUrl());
+ assertEquals(1, group.getConceptMapGroupElements().size());
+
+ //
+ element = group.getConceptMapGroupElements().get(0);
+
+ ourLog.info("ConceptMap.group(1).element(0):\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 3", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals(2, element.getConceptMapGroupElementTargets().size());
+
+ //
+ target = element.getConceptMapGroupElementTargets().get(0);
+
+ ourLog.info("ConceptMap.group(1).element(0).target(0):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+ // End ConceptMap.group(1).element(0).target(0)
+ //
+
+ //
+ target = element.getConceptMapGroupElementTargets().get(1);
+
+ ourLog.info("ConceptMap.group(1).element(0).target(1):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+ // End ConceptMap.group(1).element(0).target(1)
+ //
+
+ // End ConceptMap.group(1).element(0)
+ //
+
+ // End ConceptMap.group(1)
+ //
+
+ //
+ group = conceptMap.getConceptMapGroups().get(2);
+
+ ourLog.info("ConceptMap.group(2):\n" + group.toString());
+
+ assertEquals(CS_URL_4, group.getSource());
+ assertEquals("Version 5", group.getSourceVersion());
+ assertEquals(CS_URL_2, group.getTarget());
+ assertEquals("Version 2", group.getTargetVersion());
+ assertEquals(CM_URL, group.getConceptMapUrl());
+ assertEquals(1, group.getConceptMapGroupElements().size());
+
+ //
+ element = group.getConceptMapGroupElements().get(0);
+
+ ourLog.info("ConceptMap.group(2).element(0):\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+ assertEquals(1, element.getConceptMapGroupElementTargets().size());
+
+ //
+ target = element.getConceptMapGroupElementTargets().get(0);
+
+ ourLog.info("ConceptMap.group(2).element(0).target(0):\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.NARROWER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+ // End ConceptMap.group(2).element(0).target(0)
+ //
+
+ // End ConceptMap.group(2).element(0)
+ //
+
+ // End ConceptMap.group(2)
+ //
+
+ // End ConceptMap
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToMany() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_3));
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target(0):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(1);
+
+ ourLog.info("target(1):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeOneToOne() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_2));
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("ConceptMap.group.element.target:\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ //
+ TermConceptMapGroupElement element = target.getConceptMapGroupElement();
+
+ ourLog.info("ConceptMap.group.element:\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ TermConceptMapGroup group = element.getConceptMapGroup();
+
+ ourLog.info("ConceptMap.group:\n" + group.toString());
+
+ assertEquals(CS_URL, group.getSource());
+ assertEquals("Version 1", group.getSourceVersion());
+ assertEquals(VS_URL, group.getSourceValueSet());
+ assertEquals(CS_URL_2, group.getTarget());
+ assertEquals("Version 2", group.getTargetVersion());
+ assertEquals(VS_URL_2, group.getTargetValueSet());
+ assertEquals(CM_URL, group.getConceptMapUrl());
+
+ TermConceptMap conceptMap = group.getConceptMap();
+
+ ourLog.info("ConceptMap:\n" + conceptMap.toString());
+
+ assertNotNull(conceptMap);
+ assertEquals(VS_URL, conceptMap.getSource());
+ assertEquals(VS_URL_2, conceptMap.getTarget());
+ assertEquals(CM_URL, conceptMap.getUrl());
+ //
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateByCodeSystemsAndSourceCodeUnmapped() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("BOGUS");
+ translationRequest.setTargetSystem(new UriType(CS_URL_3));
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertTrue(targets.isEmpty());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithCodeOnly() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target(0):\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(1);
+
+ ourLog.info("target(1):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(2);
+
+ ourLog.info("target(2):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystem() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target(0):\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(1);
+
+ ourLog.info("target(1):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(2);
+
+ ourLog.info("target(2):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystemAndVersion1() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #1
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345")
+ .setVersion("Version 1");
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target:\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceSystemAndVersion3() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version #3
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345")
+ .setVersion("Version 3");
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target(0):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(1);
+
+ ourLog.info("target(1):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceAndTargetSystem2() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #2
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_2));
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target:\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(1, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceAndTargetSystem3() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #3
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL)
+ .setCode("12345");
+ translationRequest.setTargetSystem(new UriType(CS_URL_3));
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target(0):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(1);
+
+ ourLog.info("target(1):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(2, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithSourceValueSet() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source value set
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+ translationRequest.setSource(new UriType(VS_URL));
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target(0):\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(1);
+
+ ourLog.info("target(1):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(2);
+
+ ourLog.info("target(2):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateUsingPredicatesWithTargetValueSet() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * target value set
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("12345");
+ translationRequest.setTarget(new UriType(VS_URL_2));
+
+ List targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+
+ TermConceptMapGroupElementTarget target = targets.get(0);
+
+ ourLog.info("target(0):\n" + target.toString());
+
+ assertEquals("34567", target.getCode());
+ assertEquals("Target Code 34567", target.getDisplay());
+ assertEquals(CS_URL_2, target.getSystem());
+ assertEquals("Version 2", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(1);
+
+ ourLog.info("target(1):\n" + target.toString());
+
+ assertEquals("56789", target.getCode());
+ assertEquals("Target Code 56789", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ target = targets.get(2);
+
+ ourLog.info("target(2):\n" + target.toString());
+
+ assertEquals("67890", target.getCode());
+ assertEquals("Target Code 67890", target.getDisplay());
+ assertEquals(CS_URL_3, target.getSystem());
+ assertEquals("Version 4", target.getSystemVersion());
+ assertEquals(ConceptMapEquivalence.WIDER, target.getEquivalence());
+ assertEquals(VS_URL_2, target.getValueSet());
+ assertEquals(CM_URL, target.getConceptMapUrl());
+
+ // Test caching.
+ targets = myTermSvc.translate(translationRequest);
+ assertNotNull(targets);
+ assertEquals(3, targets.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverse() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(new UriType(CS_URL_4));
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseByCodeSystemsAndSourceCodeUnmapped() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ //
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_3)
+ .setCode("BOGUS");
+ translationRequest.setTargetSystem(new UriType(CS_URL));
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertTrue(elements.isEmpty());
+ //
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithCodeOnly() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ element = elements.get(1);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceSystem() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ element = elements.get(1);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceSystemAndVersion() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * source code system version
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567")
+ .setVersion("Version 2");
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ element = elements.get(1);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem1() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #1
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(new UriType(CS_URL));
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem4() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source code system
+ * target code system #4
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setSystem(CS_URL_2)
+ .setCode("34567");
+ translationRequest.setTargetSystem(new UriType(CS_URL_4));
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(1, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithSourceValueSet() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * source value set
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setSource(new UriType(VS_URL_2));
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ element = elements.get(1);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+
+ @Test
+ public void testTranslateWithReverseUsingPredicatesWithTargetValueSet() {
+ persistConceptMap();
+ ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
+
+ ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
+
+ new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
+ /*
+ * Provided:
+ * source code
+ * target value set
+ * reverse = true
+ */
+ TranslationRequest translationRequest = new TranslationRequest();
+ translationRequest.getCodeableConcept().addCoding()
+ .setCode("34567");
+ translationRequest.setTarget(new UriType(VS_URL));
+ translationRequest.setReverse(true);
+
+ List elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertFalse(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+
+ TermConceptMapGroupElement element = elements.get(0);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("12345", element.getCode());
+ assertEquals("Source Code 12345", element.getDisplay());
+ assertEquals(CS_URL, element.getSystem());
+ assertEquals("Version 1", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ element = elements.get(1);
+
+ ourLog.info("element:\n" + element.toString());
+
+ assertEquals("78901", element.getCode());
+ assertEquals("Source Code 78901", element.getDisplay());
+ assertEquals(CS_URL_4, element.getSystem());
+ assertEquals("Version 5", element.getSystemVersion());
+ assertEquals(VS_URL, element.getValueSet());
+ assertEquals(CM_URL, element.getConceptMapUrl());
+
+ // Test caching.
+ elements = myTermSvc.translateWithReverse(translationRequest);
+ assertNotNull(elements);
+ assertEquals(2, elements.size());
+ assertTrue(BaseHapiTerminologySvcImpl.isOurLastResultsFromTranslationWithReverseCache());
+ }
+ });
+ }
+}
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/interceptor/PublicSecurityInterceptor.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/interceptor/PublicSecurityInterceptor.java
index f3acbc931ea..d38fb1907f1 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/interceptor/PublicSecurityInterceptor.java
+++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/interceptor/PublicSecurityInterceptor.java
@@ -18,7 +18,7 @@ public class PublicSecurityInterceptor extends AuthorizationInterceptor {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PublicSecurityInterceptor.class);
private HashSet myTokens;
-
+
public PublicSecurityInterceptor() {
String passwordsString = System.getProperty("fhir.tdlpass");
String[] passwords = passwordsString.split(",");
diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
index 90e1a6cf67e..284871ebda7 100644
--- a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
+++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm
@@ -5,11 +5,7 @@ import java.util.*;
import org.apache.commons.lang3.StringUtils;
-#if ( $version != 'dstu' && (${className} == 'Encounter' || ${className} == 'Patient' || ${className} == 'ValueSet' || ${className} == 'QuestionnaireAnswers' || ${className} == 'CodeSystem'))
-import ca.uhn.fhir.jpa.provider${package_suffix}.BaseJpaResourceProvider${className}${versionCapitalized};
-#else
-import ca.uhn.fhir.jpa.provider${package_suffix}.JpaResourceProvider${versionCapitalized};
-#end
+import ca.uhn.fhir.jpa.provider${package_suffix}.*;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.annotation.*;
@@ -26,7 +22,7 @@ import ca.uhn.fhir.rest.api.SortSpec;
public class ${className}ResourceProvider extends
## We have specialized base classes for RPs that handle certain resource types. These
## RPs implement type specific operations
-#if ( $version != 'dstu' && (${className} == 'Encounter' || ${className} == 'Patient' || ${className} == 'ValueSet' || ${className} == 'QuestionnaireAnswers' || ${className} == 'CodeSystem'))
+#if ( $version != 'dstu' && (${className} == 'Encounter' || ${className} == 'Patient' || ${className} == 'ValueSet' || ${className} == 'QuestionnaireAnswers' || ${className} == 'CodeSystem' || ($version != 'dstu2' && ${className} == 'ConceptMap')))
BaseJpaResourceProvider${className}${versionCapitalized}
#else
JpaResourceProvider${versionCapitalized}<${className}>
diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans.vm
index 13aa1fdbd82..c5fd9c91777 100644
--- a/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans.vm
+++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans.vm
@@ -44,7 +44,11 @@
#foreach ( $res in $resources )
+#elseif ( ${versionCapitalized} == 'R4' && ${res.name} == 'ConceptMap')
+ class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
+#elseif ( ${versionCapitalized} != 'Dstu1' && ( ${res.name} == 'Bundle' || ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'ValueSet' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'SearchParameter'))
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
#else
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${versionCapitalized}">
@@ -59,4 +63,4 @@
#end
-
\ No newline at end of file
+
diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm
index cb9cee934cc..2cad6d3e9c5 100644
--- a/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm
+++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_spring_beans_java.vm
@@ -58,13 +58,21 @@ public abstract class BaseJavaConfig${versionCapitalized} extends ca.uhn.fhir.jp
IFhirResourceDaoCodeSystem
#elseif ( ${versionCapitalized} == 'R4' && ${res.name} == 'CodeSystem' )
IFhirResourceDaoCodeSystem
+#elseif ( ${versionCapitalized} == 'Dstu3' && ${res.name} == 'ConceptMap' )
+ IFhirResourceDaoConceptMap
+#elseif ( ${versionCapitalized} == 'R4' && ${res.name} == 'ConceptMap' )
+ IFhirResourceDaoConceptMap
#elseif ( ${versionCapitalized} != 'Dstu1' && ( ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'SearchParameter'))
IFhirResourceDao${res.name}<${resourcePackage}.${res.declaringClassNameComplete}>
#else
IFhirResourceDao<${resourcePackage}.${res.declaringClassNameComplete}>
#end
dao${res.declaringClassNameComplete}${versionCapitalized}() {
-#if ( ${versionCapitalized} != 'Dstu1' && ( ${res.name} == 'Bundle' || ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'ValueSet' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'SearchParameter' || ${res.name} == 'CodeSystem'))
+#if ( ${versionCapitalized} == 'Dstu3' && ${res.name} == 'ConceptMap' )
+ ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized} retVal = new ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized}();
+#elseif ( ${versionCapitalized} == 'R4' && ${res.name} == 'ConceptMap' )
+ ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized} retVal = new ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized}();
+#elseif ( ${versionCapitalized} != 'Dstu1' && ( ${res.name} == 'Bundle' || ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'ValueSet' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'SearchParameter' || ${res.name} == 'CodeSystem'))
ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized} retVal = new ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized}();
#else
ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${versionCapitalized}<${resourcePackage}.${res.declaringClassNameComplete}> retVal = new ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${versionCapitalized}<${resourcePackage}.${res.declaringClassNameComplete}>();
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 499e2d02efd..80676fabdc5 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -120,6 +120,10 @@
Fix a bug in the DSTU2 QuestionnaireResponseValidator which prevented validation
on groups with only one question. Thanks David Gileadi for the pull request!
+
+ The ConceptMap]] operation $translate]]> has been
+ implemented.
+
@@ -694,7 +698,7 @@ ALTER TABLE hfj_res_ver ALTER COLUMN res_text DROP NOT NULL;
in FHIR resource (XML/JSON) format.
- The Binary resource endpoint now supports the `X-Security-Context` header when
+ The Binary resource endpoint now supports the X-Security-Context]]> header when
reading or writing Binary contents using their native Content-Type (i.e exchanging
the raw binary with the server, as opposed to exchanging a FHIR resource).