709 the conceptmap operation called translate needs to be implemented (#923)
The ConceptMap operation $translate has been implemented.
This commit is contained in:
parent
a0c40cf98a
commit
d97fb8f5cf
|
@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
|
@ -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.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.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.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!
|
||||||
|
|
|
@ -469,6 +469,16 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava-testlib</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,13 +79,8 @@ import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.domain.SliceImpl;
|
import org.springframework.data.domain.SliceImpl;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
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 org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
@ -335,6 +330,13 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
doExpungeEverythingQuery("DELETE from " + TermConceptParentChildLink.class.getSimpleName() + " d");
|
doExpungeEverythingQuery("DELETE from " + TermConceptParentChildLink.class.getSimpleName() + " d");
|
||||||
return null;
|
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 -> {
|
txTemplate.execute(t -> {
|
||||||
doExpungeEverythingQuery("DELETE from " + TermConceptProperty.class.getSimpleName() + " d");
|
doExpungeEverythingQuery("DELETE from " + TermConceptProperty.class.getSimpleName() + " d");
|
||||||
doExpungeEverythingQuery("DELETE from " + TermConceptDesignation.class.getSimpleName() + " d");
|
doExpungeEverythingQuery("DELETE from " + TermConceptDesignation.class.getSimpleName() + " d");
|
||||||
|
|
|
@ -57,6 +57,16 @@ public class DaoConfig {
|
||||||
*/
|
*/
|
||||||
private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null;
|
private static final Integer DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION = null;
|
||||||
private IndexEnabledEnum myIndexMissingFieldsEnabled = IndexEnabledEnum.DISABLED;
|
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
|
* update setter javadoc if default changes
|
||||||
*/
|
*/
|
||||||
|
@ -557,6 +567,22 @@ public class DaoConfig {
|
||||||
myReuseCachedSearchResultsForMillis = theReuseCachedSearchResultsForMillis;
|
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
|
* 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
|
* resources that have any of the base URLs given here will be replaced with
|
||||||
|
|
|
@ -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<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||||
|
TranslationResult translate(TranslationRequest theTranslationRequest, RequestDetails theRequestDetails);
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||||
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
||||||
import ca.uhn.fhir.jpa.util.BaseIterator;
|
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.api.*;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
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.apache.commons.lang3.tuple.Pair;
|
||||||
import org.hibernate.ScrollMode;
|
import org.hibernate.ScrollMode;
|
||||||
import org.hibernate.ScrollableResults;
|
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.hibernate.query.Query;
|
||||||
import org.hl7.fhir.dstu3.model.BaseResource;
|
import org.hl7.fhir.dstu3.model.BaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
@ -2193,7 +2191,7 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
Query<Long> hibernateQuery = (Query<Long>) query;
|
Query<Long> hibernateQuery = (Query<Long>) query;
|
||||||
hibernateQuery.setFetchSize(myFetchSize);
|
hibernateQuery.setFetchSize(myFetchSize);
|
||||||
ScrollableResults scroll = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
|
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 the query resulted in extra results being requested
|
||||||
if (myAlsoIncludePids != null) {
|
if (myAlsoIncludePids != null) {
|
||||||
|
@ -2275,42 +2273,6 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScrollableResultsIterator extends BaseIterator<Long> implements Iterator<Long> {
|
|
||||||
|
|
||||||
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<Long> {
|
private class UniqueIndexIterator implements Iterator<Long> {
|
||||||
private final Set<String> myUniqueQueryStrings;
|
private final Set<String> myUniqueQueryStrings;
|
||||||
private Iterator<Long> myWrap = null;
|
private Iterator<Long> myWrap = null;
|
||||||
|
|
|
@ -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<TermConceptMap, Long> {
|
||||||
|
@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<TermConceptMap> findTermConceptMapByResourcePid(@Param("resource_pid") Long theResourcePid);
|
||||||
|
|
||||||
|
@Query("SELECT cm FROM TermConceptMap cm WHERE cm.myUrl = :url")
|
||||||
|
Optional<TermConceptMap> findTermConceptMapByUrl(@Param("url") String theUrl);
|
||||||
|
}
|
|
@ -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<TermConceptMapGroup, Long> {
|
||||||
|
@Query("DELETE FROM TermConceptMapGroup g WHERE g.myConceptMap.myId = :pid")
|
||||||
|
@Modifying
|
||||||
|
void deleteTermConceptMapGroupById(@Param("pid") Long theId);
|
||||||
|
}
|
|
@ -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<TermConceptMapGroupElement, Long> {
|
||||||
|
@Query("DELETE FROM TermConceptMapGroupElement e WHERE e.myConceptMapGroup.myConceptMap.myId = :pid")
|
||||||
|
@Modifying
|
||||||
|
void deleteTermConceptMapGroupElementById(@Param("pid") Long theId);
|
||||||
|
}
|
|
@ -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<TermConceptMapGroupElementTarget, Long> {
|
||||||
|
@Query("DELETE FROM TermConceptMapGroupElementTarget t WHERE t.myConceptMapGroupElement.myConceptMapGroup.myConceptMap.myId = :pid")
|
||||||
|
@Modifying
|
||||||
|
void deleteTermConceptMapGroupElementTargetById(@Param("pid") Long theId);
|
||||||
|
}
|
|
@ -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<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> {
|
||||||
|
@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<TermConceptMapGroupElementTarget> 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<TermConceptMapGroupElementTarget> 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<TermConceptMapGroupElement> 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<TermConceptMapGroupElement> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> {
|
||||||
|
@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<TermConceptMapGroupElementTarget> 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<TermConceptMapGroupElementTarget> 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<TermConceptMapGroupElement> 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<TermConceptMapGroupElement> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import org.hibernate.search.annotations.*;
|
import org.hibernate.search.annotations.*;
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
import org.springframework.validation.ValidationUtils;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
|
@ -49,7 +48,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
@Index(name = "IDX_CONCEPT_INDEXSTATUS", columnList = "INDEX_STATUS")
|
@Index(name = "IDX_CONCEPT_INDEXSTATUS", columnList = "INDEX_STATUS")
|
||||||
})
|
})
|
||||||
public class TermConcept implements Serializable {
|
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 org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TermConcept.class);
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
|
@ -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<TermConceptMapGroup> myConceptMapGroups;
|
||||||
|
|
||||||
|
public List<TermConceptMapGroup> 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<TermConceptMapGroupElement> myConceptMapGroupElements;
|
||||||
|
|
||||||
|
private String myConceptMapUrl;
|
||||||
|
private String mySourceValueSet;
|
||||||
|
private String myTargetValueSet;
|
||||||
|
|
||||||
|
public TermConceptMap getConceptMap() {
|
||||||
|
return myConceptMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConceptMap(TermConceptMap theTermConceptMap) {
|
||||||
|
myConceptMap = theTermConceptMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TermConceptMapGroupElement> 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<TermConceptMapGroupElementTarget> 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<TermConceptMapGroupElementTarget> 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<ConceptMap> {
|
||||||
|
@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();
|
||||||
|
|
||||||
|
// <editor-fold desc="Filters">
|
||||||
|
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<ConceptMap> dao = (IFhirResourceDaoConceptMap<ConceptMap>) 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<ConceptMap> {
|
||||||
|
@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();
|
||||||
|
|
||||||
|
// <editor-fold desc="Filters">
|
||||||
|
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<ConceptMap> dao = (IFhirResourceDaoConceptMap<ConceptMap>) 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,24 +27,32 @@ import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.dao.data.*;
|
import ca.uhn.fhir.jpa.dao.data.*;
|
||||||
import ca.uhn.fhir.jpa.entity.*;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
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.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.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import ca.uhn.fhir.util.ObjectUtil;
|
import ca.uhn.fhir.util.ObjectUtil;
|
||||||
import ca.uhn.fhir.util.StopWatch;
|
import ca.uhn.fhir.util.StopWatch;
|
||||||
import ca.uhn.fhir.util.ValidateUtil;
|
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.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import org.apache.lucene.search.Query;
|
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.FullTextEntityManager;
|
||||||
import org.hibernate.search.jpa.FullTextQuery;
|
import org.hibernate.search.jpa.FullTextQuery;
|
||||||
import org.hibernate.search.query.dsl.BooleanJunction;
|
import org.hibernate.search.query.dsl.BooleanJunction;
|
||||||
import org.hibernate.search.query.dsl.QueryBuilder;
|
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.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
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.ConceptMap;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.TransactionCallbackWithoutResult;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceContext;
|
import javax.persistence.PersistenceContext;
|
||||||
import javax.persistence.PersistenceContextType;
|
import javax.persistence.PersistenceContextType;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
import javax.persistence.criteria.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
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;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc {
|
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 org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiTerminologySvcImpl.class);
|
||||||
private static final Object PLACEHOLDER_OBJECT = new Object();
|
private static final Object PLACEHOLDER_OBJECT = new Object();
|
||||||
private static boolean ourForceSaveDeferredAlwaysForUnitTest;
|
private static boolean ourForceSaveDeferredAlwaysForUnitTest;
|
||||||
|
private static boolean ourLastResultsFromTranslationCache; // For testing.
|
||||||
|
private static boolean ourLastResultsFromTranslationWithReverseCache; // For testing.
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermCodeSystemDao myCodeSystemDao;
|
protected ITermCodeSystemDao myCodeSystemDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermConceptDao myConceptDao;
|
protected ITermConceptDao myConceptDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
protected ITermConceptMapDao myConceptMapDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermConceptMapGroupDao myConceptMapGroupDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermConceptMapGroupElementDao myConceptMapGroupElementDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermConceptMapGroupElementTargetDao myConceptMapGroupElementTargetDao;
|
||||||
|
@Autowired
|
||||||
protected ITermConceptPropertyDao myConceptPropertyDao;
|
protected ITermConceptPropertyDao myConceptPropertyDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermConceptDesignationDao myConceptDesignationDao;
|
protected ITermConceptDesignationDao myConceptDesignationDao;
|
||||||
|
@ -102,6 +125,12 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private IFhirResourceDaoCodeSystem<?, ?, ?> myCodeSystemResourceDao;
|
private IFhirResourceDaoCodeSystem<?, ?, ?> myCodeSystemResourceDao;
|
||||||
|
|
||||||
|
private Cache<TranslationQuery, List<TermConceptMapGroupElementTarget>> myTranslationCache;
|
||||||
|
private Cache<TranslationQuery, List<TermConceptMapGroupElement>> myTranslationWithReverseCache;
|
||||||
|
|
||||||
|
|
||||||
|
private int myFetchSize = DEFAULT_FETCH_SIZE;
|
||||||
|
|
||||||
private void addCodeIfNotAlreadyAdded(String theCodeSystem, ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, TermConcept theConcept) {
|
private void addCodeIfNotAlreadyAdded(String theCodeSystem, ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, TermConcept theConcept) {
|
||||||
if (theAddedCodes.add(theConcept.getCode())) {
|
if (theAddedCodes.add(theConcept.getCode())) {
|
||||||
ValueSet.ValueSetExpansionContainsComponent contains = theExpansionComponent.addContains();
|
ValueSet.ValueSetExpansionContainsComponent contains = theExpansionComponent.addContains();
|
||||||
|
@ -160,6 +189,23 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
|
||||||
return retVal;
|
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 IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource);
|
||||||
|
|
||||||
protected abstract void createOrUpdateConceptMap(ConceptMap theNextConceptMap);
|
protected abstract void createOrUpdateConceptMap(ConceptMap theNextConceptMap);
|
||||||
|
@ -869,6 +915,112 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
|
||||||
return csId;
|
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<TermConceptMap> 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<TermConceptMap> 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
|
@Override
|
||||||
public boolean supportsSystem(String theSystem) {
|
public boolean supportsSystem(String theSystem) {
|
||||||
TermCodeSystem cs = getCodeSystem(theSystem);
|
TermCodeSystem cs = getCodeSystem(theSystem);
|
||||||
|
@ -883,6 +1035,166 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TermConceptMapGroupElementTarget> translate(TranslationRequest theTranslationRequest) {
|
||||||
|
List<TermConceptMapGroupElementTarget> retVal = new ArrayList<>();
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = myEntityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<TermConceptMapGroupElementTarget> query = criteriaBuilder.createQuery(TermConceptMapGroupElementTarget.class);
|
||||||
|
Root<TermConceptMapGroupElementTarget> root = query.from(TermConceptMapGroupElementTarget.class);
|
||||||
|
|
||||||
|
Join<TermConceptMapGroupElementTarget, TermConceptMapGroupElement> elementJoin = root.join("myConceptMapGroupElement");
|
||||||
|
Join<TermConceptMapGroupElement, TermConceptMapGroup> groupJoin = elementJoin.join("myConceptMapGroup");
|
||||||
|
Join<TermConceptMapGroup, TermConceptMap> conceptMapJoin = groupJoin.join("myConceptMap");
|
||||||
|
|
||||||
|
List<TranslationQuery> translationQueries = theTranslationRequest.getTranslationQueries();
|
||||||
|
List<TermConceptMapGroupElementTarget> cachedTargets;
|
||||||
|
ArrayList<Predicate> predicates;
|
||||||
|
Coding coding;
|
||||||
|
for (TranslationQuery translationQuery : translationQueries) {
|
||||||
|
cachedTargets = myTranslationCache.getIfPresent(translationQuery);
|
||||||
|
if (cachedTargets == null) {
|
||||||
|
final List<TermConceptMapGroupElementTarget> 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<TermConceptMapGroupElementTarget> typedQuery = myEntityManager.createQuery(query.select(root));
|
||||||
|
org.hibernate.query.Query<TermConceptMapGroupElementTarget> hibernateQuery = (org.hibernate.query.Query<TermConceptMapGroupElementTarget>) typedQuery;
|
||||||
|
hibernateQuery.setFetchSize(myFetchSize);
|
||||||
|
ScrollableResults scrollableResults = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
|
||||||
|
Iterator<TermConceptMapGroupElementTarget> 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<TermConceptMapGroupElement> translateWithReverse(TranslationRequest theTranslationRequest) {
|
||||||
|
List<TermConceptMapGroupElement> retVal = new ArrayList<>();
|
||||||
|
|
||||||
|
CriteriaBuilder criteriaBuilder = myEntityManager.getCriteriaBuilder();
|
||||||
|
CriteriaQuery<TermConceptMapGroupElement> query = criteriaBuilder.createQuery(TermConceptMapGroupElement.class);
|
||||||
|
Root<TermConceptMapGroupElement> root = query.from(TermConceptMapGroupElement.class);
|
||||||
|
|
||||||
|
Join<TermConceptMapGroupElement, TermConceptMapGroupElementTarget> targetJoin = root.join("myConceptMapGroupElementTargets");
|
||||||
|
Join<TermConceptMapGroupElement, TermConceptMapGroup> groupJoin = root.join("myConceptMapGroup");
|
||||||
|
Join<TermConceptMapGroup, TermConceptMap> conceptMapJoin = groupJoin.join("myConceptMap");
|
||||||
|
|
||||||
|
List<TranslationQuery> translationQueries = theTranslationRequest.getTranslationQueries();
|
||||||
|
List<TermConceptMapGroupElement> cachedElements;
|
||||||
|
ArrayList<Predicate> predicates;
|
||||||
|
Coding coding;
|
||||||
|
for (TranslationQuery translationQuery : translationQueries) {
|
||||||
|
cachedElements = myTranslationWithReverseCache.getIfPresent(translationQuery);
|
||||||
|
if (cachedElements == null) {
|
||||||
|
final List<TermConceptMapGroupElement> 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<TermConceptMapGroupElement> typedQuery = myEntityManager.createQuery(query.select(root));
|
||||||
|
org.hibernate.query.Query<TermConceptMapGroupElement> hibernateQuery = (org.hibernate.query.Query<TermConceptMapGroupElement>) typedQuery;
|
||||||
|
hibernateQuery.setFetchSize(myFetchSize);
|
||||||
|
ScrollableResults scrollableResults = hibernateQuery.scroll(ScrollMode.FORWARD_ONLY);
|
||||||
|
Iterator<TermConceptMapGroupElement> 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<String> theConceptsStack,
|
private int validateConceptForStorage(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, ArrayList<String> theConceptsStack,
|
||||||
IdentityHashMap<TermConcept, Object> theAllConcepts) {
|
IdentityHashMap<TermConcept, Object> theAllConcepts) {
|
||||||
ValidateUtil.isTrueOrThrowInvalidRequest(theConcept.getCodeSystemVersion() != null, "CodesystemValue is null");
|
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
|
* 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) {
|
public static void setForceSaveDeferredAlwaysForUnitTest(boolean theForceSaveDeferredAlwaysForUnitTest) {
|
||||||
ourForceSaveDeferredAlwaysForUnitTest = theForceSaveDeferredAlwaysForUnitTest;
|
ourForceSaveDeferredAlwaysForUnitTest = theForceSaveDeferredAlwaysForUnitTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package ca.uhn.fhir.jpa.term;
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
import java.util.List;
|
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<org.hl7.fhir.r4.model.ValueSet> theValueSets, List<org.hl7.fhir.r4.model.ConceptMap> theConceptMaps);
|
IIdType storeNewCodeSystemVersion(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequestDetails, List<org.hl7.fhir.r4.model.ValueSet> theValueSets, List<org.hl7.fhir.r4.model.ConceptMap> theConceptMaps);
|
||||||
|
|
||||||
|
void storeTermConceptMapAndChildren(ResourceTable theResourceTable, ConceptMap theConceptMap);
|
||||||
|
|
||||||
boolean supportsSystem(String theCodeSystem);
|
boolean supportsSystem(String theCodeSystem);
|
||||||
|
|
||||||
|
List<TermConceptMapGroupElementTarget> translate(TranslationRequest theTranslationRequest);
|
||||||
|
|
||||||
|
List<TermConceptMapGroupElement> translateWithReverse(TranslationRequest theTranslationRequest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<TranslationQuery> getTranslationQueries() {
|
||||||
|
List<TranslationQuery> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<TranslationMatch> myMatches;
|
||||||
|
private StringType myMessage;
|
||||||
|
private BooleanType myResult;
|
||||||
|
|
||||||
|
public TranslationResult() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
myMatches = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TranslationMatch> getMatches() {
|
||||||
|
return myMatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatches(List<TranslationMatch> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -160,4 +160,8 @@ public class JpaConstants {
|
||||||
*/
|
*/
|
||||||
public static final String OPERATION_META_ADD = "$meta-add";
|
public static final String OPERATION_META_ADD = "$meta-add";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation name for the $translate operation
|
||||||
|
*/
|
||||||
|
public static final String OPERATION_TRANSLATE = "$translate";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<T extends Object> extends BaseIterator<T> implements Iterator<T> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,15 @@ import static org.mockito.Mockito.when;
|
||||||
public abstract class BaseJpaTest {
|
public abstract class BaseJpaTest {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaTest.class);
|
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 ServletRequestDetails mySrd;
|
||||||
protected ArrayList<IServerInterceptor> myServerInterceptorList;
|
protected ArrayList<IServerInterceptor> myServerInterceptorList;
|
||||||
protected IRequestOperationCallback myRequestOperationCallback = mock(IRequestOperationCallback.class);
|
protected IRequestOperationCallback myRequestOperationCallback = mock(IRequestOperationCallback.class);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.config.TestDstu3Config;
|
||||||
import ca.uhn.fhir.jpa.dao.*;
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
import ca.uhn.fhir.jpa.dao.data.*;
|
import ca.uhn.fhir.jpa.dao.data.*;
|
||||||
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
|
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.ResourceIndexedSearchParamString;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
|
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.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||||
import ca.uhn.fhir.jpa.util.ResourceCountCache;
|
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.jpa.validation.JpaValidationSupportChainDstu3;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.parser.StrictErrorHandler;
|
import ca.uhn.fhir.parser.StrictErrorHandler;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
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.rest.server.interceptor.IServerInterceptor;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.hibernate.search.jpa.FullTextEntityManager;
|
import org.hibernate.search.jpa.FullTextEntityManager;
|
||||||
import org.hibernate.search.jpa.Search;
|
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.hapi.ctx.IValidationSupport;
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -48,7 +51,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ -91,7 +94,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
protected IFhirResourceDao<CompartmentDefinition> myCompartmentDefinitionDao;
|
protected IFhirResourceDao<CompartmentDefinition> myCompartmentDefinitionDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myConceptMapDaoDstu3")
|
@Qualifier("myConceptMapDaoDstu3")
|
||||||
protected IFhirResourceDao<ConceptMap> myConceptMapDao;
|
protected IFhirResourceDaoConceptMap<ConceptMap> myConceptMapDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myConditionDaoDstu3")
|
@Qualifier("myConditionDaoDstu3")
|
||||||
protected IFhirResourceDao<Condition> myConditionDao;
|
protected IFhirResourceDao<Condition> myConditionDao;
|
||||||
|
@ -229,6 +232,10 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
protected IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> myValueSetDao;
|
protected IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> myValueSetDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
private JpaValidationSupportChainDstu3 myJpaValidationSupportChainDstu3;
|
private JpaValidationSupportChainDstu3 myJpaValidationSupportChainDstu3;
|
||||||
|
@Autowired
|
||||||
|
protected ITermConceptMapDao myTermConceptMapDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermConceptMapGroupElementTargetDao myTermConceptMapGroupElementTargetDao;
|
||||||
|
|
||||||
@After()
|
@After()
|
||||||
public void afterCleanupDao() {
|
public void afterCleanupDao() {
|
||||||
|
@ -315,4 +322,34 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a single {@link org.hl7.fhir.dstu3.model.ConceptMap} entity that includes:
|
||||||
|
* <br>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* One group with two elements, each identifying one target apiece.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* One group with one element, identifying two targets.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* One group with one element, identifying a target that also appears
|
||||||
|
* in the first element of the first group.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* </br>
|
||||||
|
* The first two groups identify the same source code system and different target code systems.
|
||||||
|
* </br>
|
||||||
|
* The first two groups also include an element with the same source code.
|
||||||
|
* </br>
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
// <editor-fold desc="Map one source code to multiple target codes">
|
||||||
|
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());
|
||||||
|
// </editor-fold>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,10 @@ import org.hibernate.search.jpa.Search;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
|
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
|
||||||
import org.hl7.fhir.r4.model.*;
|
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.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -48,13 +52,12 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes = {TestR4Config.class})
|
@ContextConfiguration(classes = {TestR4Config.class})
|
||||||
public abstract class BaseJpaR4Test extends BaseJpaTest {
|
public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
|
|
||||||
private static JpaValidationSupportChainR4 ourJpaValidationSupportChainR4;
|
private static JpaValidationSupportChainR4 ourJpaValidationSupportChainR4;
|
||||||
private static IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> ourValueSetDao;
|
private static IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> ourValueSetDao;
|
||||||
|
|
||||||
|
@ -102,7 +105,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
protected IFhirResourceDao<CompartmentDefinition> myCompartmentDefinitionDao;
|
protected IFhirResourceDao<CompartmentDefinition> myCompartmentDefinitionDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myConceptMapDaoR4")
|
@Qualifier("myConceptMapDaoR4")
|
||||||
protected IFhirResourceDao<ConceptMap> myConceptMapDao;
|
protected IFhirResourceDaoConceptMap<ConceptMap> myConceptMapDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myConditionDaoR4")
|
@Qualifier("myConditionDaoR4")
|
||||||
protected IFhirResourceDao<Condition> myConditionDao;
|
protected IFhirResourceDao<Condition> myConditionDao;
|
||||||
|
@ -240,6 +243,10 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
protected IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> myValueSetDao;
|
protected IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> myValueSetDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
private JpaValidationSupportChainR4 myJpaValidationSupportChainR4;
|
private JpaValidationSupportChainR4 myJpaValidationSupportChainR4;
|
||||||
|
@Autowired
|
||||||
|
protected ITermConceptMapDao myTermConceptMapDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermConceptMapGroupElementTargetDao myTermConceptMapGroupElementTargetDao;
|
||||||
|
|
||||||
@After()
|
@After()
|
||||||
public void afterCleanupDao() {
|
public void afterCleanupDao() {
|
||||||
|
@ -327,4 +334,141 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a single {@link org.hl7.fhir.r4.model.ConceptMap} entity that includes:
|
||||||
|
* <br>
|
||||||
|
* <ul>
|
||||||
|
* <li>
|
||||||
|
* One group with two elements, each identifying one target apiece.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* One group with one element, identifying two targets.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* One group with one element, identifying a target that also appears
|
||||||
|
* in the first element of the first group.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
* </br>
|
||||||
|
* The first two groups identify the same source code system and different target code systems.
|
||||||
|
* </br>
|
||||||
|
* 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() {
|
||||||
|
// <editor-fold desc="ConceptMap">
|
||||||
|
ConceptMap conceptMap = new ConceptMap();
|
||||||
|
conceptMap.setUrl(CM_URL);
|
||||||
|
|
||||||
|
conceptMap.setSource(new UriType(VS_URL));
|
||||||
|
conceptMap.setTarget(new UriType(VS_URL_2));
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(0)">
|
||||||
|
ConceptMapGroupComponent group = conceptMap.addGroup();
|
||||||
|
group.setSource(CS_URL);
|
||||||
|
group.setSourceVersion("Version 1");
|
||||||
|
group.setTarget(CS_URL_2);
|
||||||
|
group.setTargetVersion("Version 2");
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(0).element(0))">
|
||||||
|
SourceElementComponent element = group.addElement();
|
||||||
|
element.setCode("12345");
|
||||||
|
element.setDisplay("Source Code 12345");
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(0).element(0).target(0)">
|
||||||
|
TargetElementComponent target = element.addTarget();
|
||||||
|
target.setCode("34567");
|
||||||
|
target.setDisplay("Target Code 34567");
|
||||||
|
target.setEquivalence(ConceptMapEquivalence.EQUAL);
|
||||||
|
// End ConceptMap.group(0).element(0).target(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap.group(0).element(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(0).element(1))">
|
||||||
|
element = group.addElement();
|
||||||
|
element.setCode("23456");
|
||||||
|
element.setDisplay("Source Code 23456");
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(0).element(1).target(0)">
|
||||||
|
target = element.addTarget();
|
||||||
|
target.setCode("45678");
|
||||||
|
target.setDisplay("Target Code 45678");
|
||||||
|
target.setEquivalence(ConceptMapEquivalence.WIDER);
|
||||||
|
// End ConceptMap.group(0).element(1).target(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap.group(0).element(1)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap.group(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(1)">
|
||||||
|
group = conceptMap.addGroup();
|
||||||
|
group.setSource(CS_URL);
|
||||||
|
group.setSourceVersion("Version 3");
|
||||||
|
group.setTarget(CS_URL_3);
|
||||||
|
group.setTargetVersion("Version 4");
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(1).element(0))">
|
||||||
|
element = group.addElement();
|
||||||
|
element.setCode("12345");
|
||||||
|
element.setDisplay("Source Code 12345");
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(1).element(0).target(0)">
|
||||||
|
target = element.addTarget();
|
||||||
|
target.setCode("56789");
|
||||||
|
target.setDisplay("Target Code 56789");
|
||||||
|
target.setEquivalence(ConceptMapEquivalence.EQUAL);
|
||||||
|
// End ConceptMap.group(1).element(0).target(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(1).element(0).target(1)">
|
||||||
|
target = element.addTarget();
|
||||||
|
target.setCode("67890");
|
||||||
|
target.setDisplay("Target Code 67890");
|
||||||
|
target.setEquivalence(ConceptMapEquivalence.WIDER);
|
||||||
|
// End ConceptMap.group(1).element(0).target(1)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap.group(1).element(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap.group(1)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(2)">
|
||||||
|
group = conceptMap.addGroup();
|
||||||
|
group.setSource(CS_URL_4);
|
||||||
|
group.setSourceVersion("Version 5");
|
||||||
|
group.setTarget(CS_URL_2);
|
||||||
|
group.setTargetVersion("Version 2");
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(2).element(0))">
|
||||||
|
element = group.addElement();
|
||||||
|
element.setCode("78901");
|
||||||
|
element.setDisplay("Source Code 78901");
|
||||||
|
|
||||||
|
// <editor-fold desc="ConceptMap.group(2).element(0).target(0)">
|
||||||
|
target = element.addTarget();
|
||||||
|
target.setCode("34567");
|
||||||
|
target.setDisplay("Target Code 34567");
|
||||||
|
target.setEquivalence(ConceptMapEquivalence.NARROWER);
|
||||||
|
// End ConceptMap.group(2).element(0).target(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap.group(2).element(0)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap.group(2)
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// End ConceptMap
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
return conceptMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
// <editor-fold desc="Map one source code to multiple target codes">
|
||||||
|
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());
|
||||||
|
// </editor-fold>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
// <editor-fold desc="Map one source code to one target code">
|
||||||
|
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());
|
||||||
|
// </editor-fold>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
// <editor-fold desc="Attempt to map unknown source code">
|
||||||
|
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());
|
||||||
|
// </editor-fold>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
// <editor-fold desc="Attempt to map unknown source code">
|
||||||
|
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());
|
||||||
|
// </editor-fold>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,8 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.hl7.fhir.dstu3.model.Bundle;
|
import org.hl7.fhir.dstu3.model.Bundle;
|
||||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
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.hl7.fhir.dstu3.model.Patient;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -201,4 +203,56 @@ public abstract class BaseResourceProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
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<ParametersParameterComponent> getParametersByName(Parameters theParameters, String theName) {
|
||||||
|
List<ParametersParameterComponent> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,8 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
|
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.hl7.fhir.r4.model.Patient;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -215,4 +217,56 @@ public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
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<ParametersParameterComponent> getParametersByName(Parameters theParameters, String theName) {
|
||||||
|
List<ParametersParameterComponent> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -430,5 +430,4 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,7 +18,7 @@ public class PublicSecurityInterceptor extends AuthorizationInterceptor {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PublicSecurityInterceptor.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PublicSecurityInterceptor.class);
|
||||||
private HashSet<String> myTokens;
|
private HashSet<String> myTokens;
|
||||||
|
|
||||||
public PublicSecurityInterceptor() {
|
public PublicSecurityInterceptor() {
|
||||||
String passwordsString = System.getProperty("fhir.tdlpass");
|
String passwordsString = System.getProperty("fhir.tdlpass");
|
||||||
String[] passwords = passwordsString.split(",");
|
String[] passwords = passwordsString.split(",");
|
||||||
|
|
|
@ -5,11 +5,7 @@ import java.util.*;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
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}.*;
|
||||||
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.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
import ca.uhn.fhir.model.api.annotation.*;
|
import ca.uhn.fhir.model.api.annotation.*;
|
||||||
|
@ -26,7 +22,7 @@ import ca.uhn.fhir.rest.api.SortSpec;
|
||||||
public class ${className}ResourceProvider extends
|
public class ${className}ResourceProvider extends
|
||||||
## We have specialized base classes for RPs that handle certain resource types. These
|
## We have specialized base classes for RPs that handle certain resource types. These
|
||||||
## RPs implement type specific operations
|
## 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}
|
BaseJpaResourceProvider${className}${versionCapitalized}
|
||||||
#else
|
#else
|
||||||
JpaResourceProvider${versionCapitalized}<${className}>
|
JpaResourceProvider${versionCapitalized}<${className}>
|
||||||
|
|
|
@ -44,7 +44,11 @@
|
||||||
#foreach ( $res in $resources )
|
#foreach ( $res in $resources )
|
||||||
<bean id="my${res.name}Dao${versionCapitalized}"
|
<bean id="my${res.name}Dao${versionCapitalized}"
|
||||||
## Some resource types have customized DAOs for resource specific functionality
|
## Some resource types have customized DAOs for resource specific functionality
|
||||||
#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'))
|
#if ( ${versionCapitalized} == 'Dstu3' && ${res.name} == 'ConceptMap')
|
||||||
|
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
|
||||||
|
#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}">
|
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
|
||||||
#else
|
#else
|
||||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${versionCapitalized}">
|
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${versionCapitalized}">
|
||||||
|
@ -59,4 +63,4 @@
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
@ -58,13 +58,21 @@ public abstract class BaseJavaConfig${versionCapitalized} extends ca.uhn.fhir.jp
|
||||||
IFhirResourceDaoCodeSystem<org.hl7.fhir.dstu3.model.CodeSystem, org.hl7.fhir.dstu3.model.Coding, org.hl7.fhir.dstu3.model.CodeableConcept>
|
IFhirResourceDaoCodeSystem<org.hl7.fhir.dstu3.model.CodeSystem, org.hl7.fhir.dstu3.model.Coding, org.hl7.fhir.dstu3.model.CodeableConcept>
|
||||||
#elseif ( ${versionCapitalized} == 'R4' && ${res.name} == 'CodeSystem' )
|
#elseif ( ${versionCapitalized} == 'R4' && ${res.name} == 'CodeSystem' )
|
||||||
IFhirResourceDaoCodeSystem<org.hl7.fhir.r4.model.CodeSystem, org.hl7.fhir.r4.model.Coding, org.hl7.fhir.r4.model.CodeableConcept>
|
IFhirResourceDaoCodeSystem<org.hl7.fhir.r4.model.CodeSystem, org.hl7.fhir.r4.model.Coding, org.hl7.fhir.r4.model.CodeableConcept>
|
||||||
|
#elseif ( ${versionCapitalized} == 'Dstu3' && ${res.name} == 'ConceptMap' )
|
||||||
|
IFhirResourceDaoConceptMap<org.hl7.fhir.dstu3.model.ConceptMap>
|
||||||
|
#elseif ( ${versionCapitalized} == 'R4' && ${res.name} == 'ConceptMap' )
|
||||||
|
IFhirResourceDaoConceptMap<org.hl7.fhir.r4.model.ConceptMap>
|
||||||
#elseif ( ${versionCapitalized} != 'Dstu1' && ( ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'SearchParameter'))
|
#elseif ( ${versionCapitalized} != 'Dstu1' && ( ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'SearchParameter'))
|
||||||
IFhirResourceDao${res.name}<${resourcePackage}.${res.declaringClassNameComplete}>
|
IFhirResourceDao${res.name}<${resourcePackage}.${res.declaringClassNameComplete}>
|
||||||
#else
|
#else
|
||||||
IFhirResourceDao<${resourcePackage}.${res.declaringClassNameComplete}>
|
IFhirResourceDao<${resourcePackage}.${res.declaringClassNameComplete}>
|
||||||
#end
|
#end
|
||||||
dao${res.declaringClassNameComplete}${versionCapitalized}() {
|
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}();
|
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
|
#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}>();
|
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}>();
|
||||||
|
|
|
@ -120,6 +120,10 @@
|
||||||
Fix a bug in the DSTU2 QuestionnaireResponseValidator which prevented validation
|
Fix a bug in the DSTU2 QuestionnaireResponseValidator which prevented validation
|
||||||
on groups with only one question. Thanks David Gileadi for the pull request!
|
on groups with only one question. Thanks David Gileadi for the pull request!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add" issue="709">
|
||||||
|
The <![CDATA[<code>ConceptMap</code>]] operation <![CDATA[<code>$translate</code>]]> has been
|
||||||
|
implemented.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.3.0" date="2018-03-29">
|
<release version="3.3.0" date="2018-03-29">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
@ -694,7 +698,7 @@ ALTER TABLE hfj_res_ver ALTER COLUMN res_text DROP NOT NULL;</pre>
|
||||||
in FHIR resource (XML/JSON) format.
|
in FHIR resource (XML/JSON) format.
|
||||||
</action>
|
</action>
|
||||||
<action type="add">
|
<action type="add">
|
||||||
The Binary resource endpoint now supports the `X-Security-Context` header when
|
The Binary resource endpoint now supports the <![CDATA[<code>X-Security-Context</code>]]> header when
|
||||||
reading or writing Binary contents using their native Content-Type (i.e exchanging
|
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).
|
the raw binary with the server, as opposed to exchanging a FHIR resource).
|
||||||
</action>
|
</action>
|
||||||
|
|
Loading…
Reference in New Issue