Merge remote-tracking branch 'remotes/origin/master' into add-pid-to-created-resource
This commit is contained in:
commit
79ce4a30cc
|
@ -20,16 +20,16 @@ package ca.uhn.fhir.jpa.dao.data;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSetCode;
|
import ca.uhn.fhir.jpa.entity.TermValueSetConcept;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
public interface ITermValueSetCodeDao extends JpaRepository<TermValueSetCode, Long> {
|
public interface ITermValueSetConceptDao extends JpaRepository<TermValueSetConcept, Long> {
|
||||||
|
|
||||||
@Query("DELETE FROM TermValueSetCode vsc WHERE vsc.myValueSet.myId = :pid")
|
@Query("DELETE FROM TermValueSetConcept vsc WHERE vsc.myValueSet.myId = :pid")
|
||||||
@Modifying
|
@Modifying
|
||||||
void deleteTermValueSetCodesByValueSetId(@Param("pid") Long theValueSetId);
|
void deleteTermValueSetConceptsByValueSetId(@Param("pid") Long theValueSetId);
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2019 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.entity.TermValueSetConceptDesignation;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public interface ITermValueSetConceptDesignationDao extends JpaRepository<TermValueSetConceptDesignation, Long> {
|
||||||
|
|
||||||
|
@Query("DELETE FROM TermValueSetConceptDesignation vscd WHERE vscd.myConcept.myValueSet.myId = :pid")
|
||||||
|
@Modifying
|
||||||
|
void deleteTermValueSetConceptDesignationsByValueSetId(@Param("pid") Long theValueSetId);
|
||||||
|
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
|
@ -51,8 +52,7 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
|
public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
|
||||||
|
|
||||||
|
@ -193,6 +193,21 @@ public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSys
|
||||||
termConcept.setDisplay(next.getDisplay());
|
termConcept.setDisplay(next.getDisplay());
|
||||||
termConcept.addChildren(toPersistedConcepts(next.getConcept(), theCodeSystemVersion), RelationshipTypeEnum.ISA);
|
termConcept.addChildren(toPersistedConcepts(next.getConcept(), theCodeSystemVersion), RelationshipTypeEnum.ISA);
|
||||||
retVal.add(termConcept);
|
retVal.add(termConcept);
|
||||||
|
|
||||||
|
for (CodeSystem.ConceptDefinitionDesignationComponent designationComponent : next.getDesignation()) {
|
||||||
|
if (isNotBlank(designationComponent.getValue())) {
|
||||||
|
TermConceptDesignation designation = termConcept.addDesignation();
|
||||||
|
designation.setLanguage(designationComponent.hasLanguage() ? designationComponent.getLanguage() : null);
|
||||||
|
if (designationComponent.hasUse()) {
|
||||||
|
designation.setUseSystem(designationComponent.getUse().hasSystem() ? designationComponent.getUse().getSystem() : null);
|
||||||
|
designation.setUseCode(designationComponent.getUse().hasCode() ? designationComponent.getUse().getCode() : null);
|
||||||
|
designation.setUseDisplay(designationComponent.getUse().hasDisplay() ? designationComponent.getUse().getDisplay() : null);
|
||||||
|
}
|
||||||
|
designation.setValue(designationComponent.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: DM 2019-07-16 - We should also populate TermConceptProperty entities here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,8 @@ public class ExpungeEverythingService {
|
||||||
counter.addAndGet(expungeEverythingByType(ResourceLink.class));
|
counter.addAndGet(expungeEverythingByType(ResourceLink.class));
|
||||||
counter.addAndGet(expungeEverythingByType(SearchResult.class));
|
counter.addAndGet(expungeEverythingByType(SearchResult.class));
|
||||||
counter.addAndGet(expungeEverythingByType(SearchInclude.class));
|
counter.addAndGet(expungeEverythingByType(SearchInclude.class));
|
||||||
counter.addAndGet(expungeEverythingByType(TermValueSetCode.class));
|
counter.addAndGet(expungeEverythingByType(TermValueSetConceptDesignation.class));
|
||||||
|
counter.addAndGet(expungeEverythingByType(TermValueSetConcept.class));
|
||||||
counter.addAndGet(expungeEverythingByType(TermValueSet.class));
|
counter.addAndGet(expungeEverythingByType(TermValueSet.class));
|
||||||
counter.addAndGet(expungeEverythingByType(TermConceptParentChildLink.class));
|
counter.addAndGet(expungeEverythingByType(TermConceptParentChildLink.class));
|
||||||
counter.addAndGet(expungeEverythingByType(TermConceptMapGroupElementTarget.class));
|
counter.addAndGet(expungeEverythingByType(TermConceptMapGroupElementTarget.class));
|
||||||
|
|
|
@ -26,8 +26,8 @@ import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
||||||
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.util.LogicUtil;
|
import ca.uhn.fhir.jpa.util.LogicUtil;
|
||||||
|
@ -52,8 +52,7 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
public class FhirResourceDaoCodeSystemR4 extends FhirResourceDaoR4<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
|
public class FhirResourceDaoCodeSystemR4 extends FhirResourceDaoR4<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
|
||||||
|
|
||||||
|
@ -168,6 +167,21 @@ public class FhirResourceDaoCodeSystemR4 extends FhirResourceDaoR4<CodeSystem> i
|
||||||
termConcept.setDisplay(next.getDisplay());
|
termConcept.setDisplay(next.getDisplay());
|
||||||
termConcept.addChildren(toPersistedConcepts(next.getConcept(), theCodeSystemVersion), RelationshipTypeEnum.ISA);
|
termConcept.addChildren(toPersistedConcepts(next.getConcept(), theCodeSystemVersion), RelationshipTypeEnum.ISA);
|
||||||
retVal.add(termConcept);
|
retVal.add(termConcept);
|
||||||
|
|
||||||
|
for (CodeSystem.ConceptDefinitionDesignationComponent designationComponent : next.getDesignation()) {
|
||||||
|
if (isNotBlank(designationComponent.getValue())) {
|
||||||
|
TermConceptDesignation designation = termConcept.addDesignation();
|
||||||
|
designation.setLanguage(designationComponent.hasLanguage() ? designationComponent.getLanguage() : null);
|
||||||
|
if (designationComponent.hasUse()) {
|
||||||
|
designation.setUseSystem(designationComponent.getUse().hasSystem() ? designationComponent.getUse().getSystem() : null);
|
||||||
|
designation.setUseCode(designationComponent.getUse().hasCode() ? designationComponent.getUse().getCode() : null);
|
||||||
|
designation.setUseDisplay(designationComponent.getUse().hasDisplay() ? designationComponent.getUse().getDisplay() : null);
|
||||||
|
}
|
||||||
|
designation.setValue(designationComponent.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: DM 2019-07-16 - We should also populate TermConceptProperty entities here.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,6 @@ public class TermConceptDesignation implements Serializable {
|
||||||
public TermConceptDesignation setUseSystem(String theUseSystem) {
|
public TermConceptDesignation setUseSystem(String theUseSystem) {
|
||||||
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theUseSystem, MAX_LENGTH,
|
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theUseSystem, MAX_LENGTH,
|
||||||
"Use system exceeds maximum length (" + MAX_LENGTH + "): " + length(theUseSystem));
|
"Use system exceeds maximum length (" + MAX_LENGTH + "): " + length(theUseSystem));
|
||||||
|
|
||||||
myUseSystem = theUseSystem;
|
myUseSystem = theUseSystem;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class TermValueSet implements Serializable {
|
||||||
private String myName;
|
private String myName;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "myValueSet")
|
@OneToMany(mappedBy = "myValueSet")
|
||||||
private List<TermValueSetCode> myCodes;
|
private List<TermValueSetConcept> myConcepts;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return myId;
|
return myId;
|
||||||
|
@ -102,12 +102,12 @@ public class TermValueSet implements Serializable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TermValueSetCode> getCodes() {
|
public List<TermValueSetConcept> getConcepts() {
|
||||||
if (myCodes == null) {
|
if (myConcepts == null) {
|
||||||
myCodes = new ArrayList<>();
|
myConcepts = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return myCodes;
|
return myConcepts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -138,7 +138,7 @@ public class TermValueSet implements Serializable {
|
||||||
.append(myResource != null ? ("myResource=" + myResource.toString()) : ("myResource=(null)"))
|
.append(myResource != null ? ("myResource=" + myResource.toString()) : ("myResource=(null)"))
|
||||||
.append("myResourcePid", myResourcePid)
|
.append("myResourcePid", myResourcePid)
|
||||||
.append("myName", myName)
|
.append("myName", myName)
|
||||||
.append(myCodes != null ? ("myCodes - size=" + myCodes.size()) : ("myCodes=(null)"))
|
.append(myConcepts != null ? ("myConcepts - size=" + myConcepts.size()) : ("myConcepts=(null)"))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,20 +29,22 @@ import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.left;
|
import static org.apache.commons.lang3.StringUtils.left;
|
||||||
import static org.apache.commons.lang3.StringUtils.length;
|
import static org.apache.commons.lang3.StringUtils.length;
|
||||||
|
|
||||||
@Table(name = "TRM_VALUESET_CODE", indexes = {
|
@Table(name = "TRM_VALUESET_CONCEPT", indexes = {
|
||||||
@Index(name = "IDX_VALUESET_CODE_CS_CD", columnList = "SYSTEM, CODE")
|
@Index(name = "IDX_VALUESET_CONCEPT_CS_CD", columnList = "SYSTEM, CODE")
|
||||||
})
|
})
|
||||||
@Entity()
|
@Entity()
|
||||||
public class TermValueSetCode implements Serializable {
|
public class TermValueSetConcept implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id()
|
@Id()
|
||||||
@SequenceGenerator(name = "SEQ_VALUESET_CODE_PID", sequenceName = "SEQ_VALUESET_CODE_PID")
|
@SequenceGenerator(name = "SEQ_VALUESET_CONCEPT_PID", sequenceName = "SEQ_VALUESET_CONCEPT_PID")
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_VALUESET_CODE_PID")
|
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_VALUESET_CONCEPT_PID")
|
||||||
@Column(name = "PID")
|
@Column(name = "PID")
|
||||||
private Long myId;
|
private Long myId;
|
||||||
|
|
||||||
|
@ -65,6 +67,9 @@ public class TermValueSetCode implements Serializable {
|
||||||
@Column(name = "DISPLAY", nullable = true, length = TermConcept.MAX_DESC_LENGTH)
|
@Column(name = "DISPLAY", nullable = true, length = TermConcept.MAX_DESC_LENGTH)
|
||||||
private String myDisplay;
|
private String myDisplay;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "myConcept")
|
||||||
|
private List<TermValueSetConceptDesignation> myDesignations;
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return myId;
|
return myId;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +78,7 @@ public class TermValueSetCode implements Serializable {
|
||||||
return myValueSet;
|
return myValueSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TermValueSetCode setValueSet(TermValueSet theValueSet) {
|
public TermValueSetConcept setValueSet(TermValueSet theValueSet) {
|
||||||
myValueSet = theValueSet;
|
myValueSet = theValueSet;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +103,7 @@ public class TermValueSetCode implements Serializable {
|
||||||
return mySystem;
|
return mySystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TermValueSetCode setSystem(@Nonnull String theSystem) {
|
public TermValueSetConcept setSystem(@Nonnull String theSystem) {
|
||||||
ValidateUtil.isNotBlankOrThrowIllegalArgument(theSystem, "theSystem must not be null or empty");
|
ValidateUtil.isNotBlankOrThrowIllegalArgument(theSystem, "theSystem must not be null or empty");
|
||||||
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theSystem, TermCodeSystem.MAX_URL_LENGTH,
|
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theSystem, TermCodeSystem.MAX_URL_LENGTH,
|
||||||
"System exceeds maximum length (" + TermCodeSystem.MAX_URL_LENGTH + "): " + length(theSystem));
|
"System exceeds maximum length (" + TermCodeSystem.MAX_URL_LENGTH + "): " + length(theSystem));
|
||||||
|
@ -110,7 +115,7 @@ public class TermValueSetCode implements Serializable {
|
||||||
return myCode;
|
return myCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TermValueSetCode setCode(@Nonnull String theCode) {
|
public TermValueSetConcept setCode(@Nonnull String theCode) {
|
||||||
ValidateUtil.isNotBlankOrThrowIllegalArgument(theCode, "theCode must not be null or empty");
|
ValidateUtil.isNotBlankOrThrowIllegalArgument(theCode, "theCode must not be null or empty");
|
||||||
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theCode, TermConcept.MAX_CODE_LENGTH,
|
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theCode, TermConcept.MAX_CODE_LENGTH,
|
||||||
"Code exceeds maximum length (" + TermConcept.MAX_CODE_LENGTH + "): " + length(theCode));
|
"Code exceeds maximum length (" + TermConcept.MAX_CODE_LENGTH + "): " + length(theCode));
|
||||||
|
@ -122,18 +127,26 @@ public class TermValueSetCode implements Serializable {
|
||||||
return myDisplay;
|
return myDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TermValueSetCode setDisplay(String theDisplay) {
|
public TermValueSetConcept setDisplay(String theDisplay) {
|
||||||
myDisplay = left(theDisplay, TermConcept.MAX_DESC_LENGTH);
|
myDisplay = left(theDisplay, TermConcept.MAX_DESC_LENGTH);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TermValueSetConceptDesignation> getDesignations() {
|
||||||
|
if (myDesignations == null) {
|
||||||
|
myDesignations = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return myDesignations;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object theO) {
|
public boolean equals(Object theO) {
|
||||||
if (this == theO) return true;
|
if (this == theO) return true;
|
||||||
|
|
||||||
if (!(theO instanceof TermValueSetCode)) return false;
|
if (!(theO instanceof TermValueSetConcept)) return false;
|
||||||
|
|
||||||
TermValueSetCode that = (TermValueSetCode) theO;
|
TermValueSetConcept that = (TermValueSetConcept) theO;
|
||||||
|
|
||||||
return new EqualsBuilder()
|
return new EqualsBuilder()
|
||||||
.append(getValueSetUrl(), that.getValueSetUrl())
|
.append(getValueSetUrl(), that.getValueSetUrl())
|
||||||
|
@ -161,6 +174,7 @@ public class TermValueSetCode implements Serializable {
|
||||||
.append("mySystem", mySystem)
|
.append("mySystem", mySystem)
|
||||||
.append("myCode", myCode)
|
.append("myCode", myCode)
|
||||||
.append("myDisplay", myDisplay)
|
.append("myDisplay", myDisplay)
|
||||||
|
.append(myDesignations != null ? ("myDesignations - size=" + myDesignations.size()) : ("myDesignations=(null)"))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
package ca.uhn.fhir.jpa.entity;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2019 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.util.ValidateUtil;
|
||||||
|
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.annotation.Nonnull;
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.left;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.length;
|
||||||
|
|
||||||
|
@Table(name = "TRM_VALUESET_C_DESIGNATION", indexes = {
|
||||||
|
@Index(name = "IDX_VALUESET_C_DSGNTN_VAL", columnList = "VAL")
|
||||||
|
})
|
||||||
|
@Entity()
|
||||||
|
public class TermValueSetConceptDesignation implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final int MAX_LENGTH = 500;
|
||||||
|
|
||||||
|
@Id()
|
||||||
|
@SequenceGenerator(name = "SEQ_VALUESET_C_DSGNTN_PID", sequenceName = "SEQ_VALUESET_C_DSGNTN_PID")
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_VALUESET_C_DSGNTN_PID")
|
||||||
|
@Column(name = "PID")
|
||||||
|
private Long myId;
|
||||||
|
|
||||||
|
@ManyToOne()
|
||||||
|
@JoinColumn(name = "VALUESET_CONCEPT_PID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_TRM_VALUESET_CONCEPT_PID"))
|
||||||
|
private TermValueSetConcept myConcept;
|
||||||
|
|
||||||
|
@Column(name = "LANG", nullable = true, length = MAX_LENGTH)
|
||||||
|
private String myLanguage;
|
||||||
|
|
||||||
|
@Column(name = "USE_SYSTEM", nullable = true, length = MAX_LENGTH)
|
||||||
|
private String myUseSystem;
|
||||||
|
|
||||||
|
@Column(name = "USE_CODE", nullable = true, length = MAX_LENGTH)
|
||||||
|
private String myUseCode;
|
||||||
|
|
||||||
|
@Column(name = "USE_DISPLAY", nullable = true, length = MAX_LENGTH)
|
||||||
|
private String myUseDisplay;
|
||||||
|
|
||||||
|
@Column(name = "VAL", nullable = false, length = MAX_LENGTH)
|
||||||
|
private String myValue;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return myId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermValueSetConcept getConcept() {
|
||||||
|
return myConcept;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermValueSetConceptDesignation setConcept(TermValueSetConcept theConcept) {
|
||||||
|
myConcept = theConcept;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLanguage() {
|
||||||
|
return myLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermValueSetConceptDesignation setLanguage(String theLanguage) {
|
||||||
|
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theLanguage, MAX_LENGTH,
|
||||||
|
"Language exceeds maximum length (" + MAX_LENGTH + "): " + length(theLanguage));
|
||||||
|
myLanguage = theLanguage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUseSystem() {
|
||||||
|
return myUseSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermValueSetConceptDesignation setUseSystem(String theUseSystem) {
|
||||||
|
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theUseSystem, MAX_LENGTH,
|
||||||
|
"Use system exceeds maximum length (" + MAX_LENGTH + "): " + length(theUseSystem));
|
||||||
|
myUseSystem = theUseSystem;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUseCode() {
|
||||||
|
return myUseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermValueSetConceptDesignation setUseCode(String theUseCode) {
|
||||||
|
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theUseCode, MAX_LENGTH,
|
||||||
|
"Use code exceeds maximum length (" + MAX_LENGTH + "): " + length(theUseCode));
|
||||||
|
myUseCode = theUseCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUseDisplay() {
|
||||||
|
return myUseDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermValueSetConceptDesignation setUseDisplay(String theUseDisplay) {
|
||||||
|
myUseDisplay = left(theUseDisplay, MAX_LENGTH);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return myValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermValueSetConceptDesignation setValue(@Nonnull String theValue) {
|
||||||
|
ValidateUtil.isNotBlankOrThrowIllegalArgument(theValue, "theValue must not be null or empty");
|
||||||
|
ValidateUtil.isNotTooLongOrThrowIllegalArgument(theValue, MAX_LENGTH,
|
||||||
|
"Value exceeds maximum length (" + MAX_LENGTH + "): " + length(theValue));
|
||||||
|
myValue = theValue;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object theO) {
|
||||||
|
if (this == theO) return true;
|
||||||
|
|
||||||
|
if (!(theO instanceof TermValueSetConceptDesignation)) return false;
|
||||||
|
|
||||||
|
TermValueSetConceptDesignation that = (TermValueSetConceptDesignation) theO;
|
||||||
|
|
||||||
|
return new EqualsBuilder()
|
||||||
|
.append(getLanguage(), that.getLanguage())
|
||||||
|
.append(getUseSystem(), that.getUseSystem())
|
||||||
|
.append(getUseCode(), that.getUseCode())
|
||||||
|
.append(getUseDisplay(), that.getUseDisplay())
|
||||||
|
.append(getValue(), that.getValue())
|
||||||
|
.isEquals();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return new HashCodeBuilder(17, 37)
|
||||||
|
.append(getLanguage())
|
||||||
|
.append(getUseSystem())
|
||||||
|
.append(getUseCode())
|
||||||
|
.append(getUseDisplay())
|
||||||
|
.append(getValue())
|
||||||
|
.toHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
||||||
|
.append("myId", myId)
|
||||||
|
.append(myConcept != null ? ("myConcept - id=" + myConcept.getId()) : ("myConcept=(null)"))
|
||||||
|
.append("myLanguage", myLanguage)
|
||||||
|
.append("myUseSystem", myUseSystem)
|
||||||
|
.append("myUseCode", myUseCode)
|
||||||
|
.append("myUseDisplay", myUseDisplay)
|
||||||
|
.append("myValue", myValue)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -91,8 +91,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc, ApplicationContextAware {
|
public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc, ApplicationContextAware {
|
||||||
public static final int DEFAULT_FETCH_SIZE = 250;
|
public static final int DEFAULT_FETCH_SIZE = 250;
|
||||||
|
@ -121,7 +120,9 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermValueSetDao myValueSetDao;
|
protected ITermValueSetDao myValueSetDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermValueSetCodeDao myValueSetCodeDao;
|
protected ITermValueSetConceptDao myValueSetConceptDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermValueSetConceptDesignationDao myValueSetConceptDesignationDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected FhirContext myContext;
|
protected FhirContext myContext;
|
||||||
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
||||||
|
@ -152,54 +153,39 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private IFulltextSearchSvc myFulltextSearchSvc;
|
private IFulltextSearchSvc myFulltextSearchSvc;
|
||||||
|
|
||||||
|
private void addCodeIfNotAlreadyAdded(IValueSetCodeAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, TermConcept theConcept, boolean theAdd, AtomicInteger theCodeCounter) {
|
||||||
private void addCodeIfNotAlreadyAdded(ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, TermConcept theConcept, boolean theAdd, AtomicInteger theCodeCounter) {
|
|
||||||
String codeSystem = theConcept.getCodeSystemVersion().getCodeSystem().getCodeSystemUri();
|
String codeSystem = theConcept.getCodeSystemVersion().getCodeSystem().getCodeSystemUri();
|
||||||
String code = theConcept.getCode();
|
String code = theConcept.getCode();
|
||||||
String display = theConcept.getDisplay();
|
String display = theConcept.getDisplay();
|
||||||
Collection<TermConceptDesignation> designations = theConcept.getDesignations();
|
Collection<TermConceptDesignation> designations = theConcept.getDesignations();
|
||||||
addCodeIfNotAlreadyAdded(theExpansionComponent, theAddedCodes, designations, theAdd, theCodeCounter, codeSystem, code, display);
|
addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, designations, theAdd, theCodeCounter, codeSystem, code, display);
|
||||||
}
|
|
||||||
|
|
||||||
private void addCodeIfNotAlreadyAdded(ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, Collection<TermConceptDesignation> theDesignations, boolean theAdd, AtomicInteger theCodeCounter, String theCodeSystem, String theCode, String theDisplay) {
|
|
||||||
if (isNotBlank(theCode) && theAdd && theAddedCodes.add(theCode)) {
|
|
||||||
ValueSet.ValueSetExpansionContainsComponent contains = theExpansionComponent.addContains();
|
|
||||||
contains.setCode(theCode);
|
|
||||||
contains.setSystem(theCodeSystem);
|
|
||||||
contains.setDisplay(theDisplay);
|
|
||||||
if (theDesignations != null) {
|
|
||||||
for (TermConceptDesignation nextDesignation : theDesignations) {
|
|
||||||
contains
|
|
||||||
.addDesignation()
|
|
||||||
.setValue(nextDesignation.getValue())
|
|
||||||
.getUse()
|
|
||||||
.setSystem(nextDesignation.getUseSystem())
|
|
||||||
.setCode(nextDesignation.getUseCode())
|
|
||||||
.setDisplay(nextDesignation.getUseDisplay());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addCodeIfNotAlreadyAdded(IValueSetCodeAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, Collection<TermConceptDesignation> theDesignations, boolean theAdd, AtomicInteger theCodeCounter, String theCodeSystem, String theCode, String theDisplay) {
|
||||||
|
if (isNoneBlank(theCodeSystem, theCode)) {
|
||||||
|
if (theAdd && theAddedCodes.add(theCodeSystem + "|" + theCode)) {
|
||||||
|
theValueSetCodeAccumulator.includeCodeWithDesignations(theCodeSystem, theCode, theDisplay, theDesignations);
|
||||||
theCodeCounter.incrementAndGet();
|
theCodeCounter.incrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!theAdd && theAddedCodes.remove(theCode)) {
|
if (!theAdd && theAddedCodes.remove(theCodeSystem + "|" + theCode)) {
|
||||||
removeCodeFromExpansion(theCodeSystem, theCode, theExpansionComponent);
|
theValueSetCodeAccumulator.excludeCode(theCodeSystem, theCode);
|
||||||
theCodeCounter.decrementAndGet();
|
theCodeCounter.decrementAndGet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addConceptsToList(ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, String theSystem, List<CodeSystem.ConceptDefinitionComponent> theConcept, boolean theAdd) {
|
private void addConceptsToList(IValueSetCodeAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, String theSystem, List<CodeSystem.ConceptDefinitionComponent> theConcept, boolean theAdd) {
|
||||||
for (CodeSystem.ConceptDefinitionComponent next : theConcept) {
|
for (CodeSystem.ConceptDefinitionComponent next : theConcept) {
|
||||||
if (theAdd && theAddedCodes.add(next.getCode())) {
|
if (isNoneBlank(theSystem, next.getCode())) {
|
||||||
ValueSet.ValueSetExpansionContainsComponent contains = theExpansionComponent.addContains();
|
if (theAdd && theAddedCodes.add(theSystem + "|" + next.getCode())) {
|
||||||
contains.setCode(next.getCode());
|
theValueSetCodeAccumulator.includeCode(theSystem, next.getCode(), next.getDisplay());
|
||||||
contains.setSystem(theSystem);
|
|
||||||
contains.setDisplay(next.getDisplay());
|
|
||||||
}
|
}
|
||||||
if (!theAdd && theAddedCodes.remove(next.getCode())) {
|
if (!theAdd && theAddedCodes.remove(theSystem + "|" + next.getCode())) {
|
||||||
removeCodeFromExpansion(theSystem, next.getCode(), theExpansionComponent);
|
theValueSetCodeAccumulator.excludeCode(theSystem, next.getCode());
|
||||||
}
|
}
|
||||||
addConceptsToList(theExpansionComponent, theAddedCodes, theSystem, next.getConcept(), theAdd);
|
}
|
||||||
|
addConceptsToList(theValueSetCodeAccumulator, theAddedCodes, theSystem, next.getConcept(), theAdd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,12 +386,14 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
TermValueSet existingTermValueSet = optionalExistingTermValueSetById.get();
|
TermValueSet existingTermValueSet = optionalExistingTermValueSetById.get();
|
||||||
|
|
||||||
ourLog.info("Deleting existing TermValueSet {} and its children...", existingTermValueSet.getId());
|
ourLog.info("Deleting existing TermValueSet {} and its children...", existingTermValueSet.getId());
|
||||||
myValueSetCodeDao.deleteTermValueSetCodesByValueSetId(existingTermValueSet.getId());
|
myValueSetConceptDesignationDao.deleteTermValueSetConceptDesignationsByValueSetId(existingTermValueSet.getId());
|
||||||
|
myValueSetConceptDao.deleteTermValueSetConceptsByValueSetId(existingTermValueSet.getId());
|
||||||
myValueSetDao.deleteTermValueSetById(existingTermValueSet.getId());
|
myValueSetDao.deleteTermValueSetById(existingTermValueSet.getId());
|
||||||
ourLog.info("Done deleting existing TermValueSet {} and its children.", existingTermValueSet.getId());
|
ourLog.info("Done deleting existing TermValueSet {} and its children.", existingTermValueSet.getId());
|
||||||
|
|
||||||
ourLog.info("Flushing...");
|
ourLog.info("Flushing...");
|
||||||
myValueSetCodeDao.flush();
|
myValueSetConceptDesignationDao.flush();
|
||||||
|
myValueSetConceptDao.flush();
|
||||||
myValueSetDao.flush();
|
myValueSetDao.flush();
|
||||||
ourLog.info("Done flushing.");
|
ourLog.info("Done flushing.");
|
||||||
}
|
}
|
||||||
|
@ -466,26 +454,13 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
public ValueSet expandValueSet(ValueSet theValueSetToExpand) {
|
public ValueSet expandValueSet(ValueSet theValueSetToExpand) {
|
||||||
|
|
||||||
ValueSet.ValueSetExpansionComponent expansionComponent = new ValueSet.ValueSetExpansionComponent();
|
ValueSetExpansionComponentWithCodeAccumulator expansionComponent = new ValueSetExpansionComponentWithCodeAccumulator();
|
||||||
expansionComponent.setIdentifier(UUID.randomUUID().toString());
|
expansionComponent.setIdentifier(UUID.randomUUID().toString());
|
||||||
expansionComponent.setTimestamp(new Date());
|
expansionComponent.setTimestamp(new Date());
|
||||||
|
|
||||||
Set<String> addedCodes = new HashSet<>();
|
|
||||||
AtomicInteger codeCounter = new AtomicInteger(0);
|
AtomicInteger codeCounter = new AtomicInteger(0);
|
||||||
|
|
||||||
// Handle includes
|
expandValueSet(theValueSetToExpand, expansionComponent, codeCounter);
|
||||||
ourLog.debug("Handling includes");
|
|
||||||
for (ValueSet.ConceptSetComponent include : theValueSetToExpand.getCompose().getInclude()) {
|
|
||||||
boolean add = true;
|
|
||||||
expandValueSetHandleIncludeOrExclude(expansionComponent, addedCodes, include, add, codeCounter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle excludes
|
|
||||||
ourLog.debug("Handling excludes");
|
|
||||||
for (ValueSet.ConceptSetComponent include : theValueSetToExpand.getCompose().getExclude()) {
|
|
||||||
boolean add = false;
|
|
||||||
expandValueSetHandleIncludeOrExclude(expansionComponent, addedCodes, include, add, codeCounter);
|
|
||||||
}
|
|
||||||
|
|
||||||
expansionComponent.setTotal(codeCounter.get());
|
expansionComponent.setTotal(codeCounter.get());
|
||||||
|
|
||||||
|
@ -496,6 +471,30 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
return valueSet;
|
return valueSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
|
public void expandValueSet(ValueSet theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator) {
|
||||||
|
expandValueSet(theValueSetToExpand, theValueSetCodeAccumulator, new AtomicInteger(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expandValueSet(ValueSet theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator, AtomicInteger theCodeCounter) {
|
||||||
|
Set<String> addedCodes = new HashSet<>();
|
||||||
|
|
||||||
|
// Handle includes
|
||||||
|
ourLog.debug("Handling includes");
|
||||||
|
for (ValueSet.ConceptSetComponent include : theValueSetToExpand.getCompose().getInclude()) {
|
||||||
|
boolean add = true;
|
||||||
|
expandValueSetHandleIncludeOrExclude(theValueSetCodeAccumulator, addedCodes, include, add, theCodeCounter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle excludes
|
||||||
|
ourLog.debug("Handling excludes");
|
||||||
|
for (ValueSet.ConceptSetComponent include : theValueSetToExpand.getCompose().getExclude()) {
|
||||||
|
boolean add = false;
|
||||||
|
expandValueSetHandleIncludeOrExclude(theValueSetCodeAccumulator, addedCodes, include, add, theCodeCounter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected List<VersionIndependentConcept> expandValueSetAndReturnVersionIndependentConcepts(org.hl7.fhir.r4.model.ValueSet theValueSetToExpandR4) {
|
protected List<VersionIndependentConcept> expandValueSetAndReturnVersionIndependentConcepts(org.hl7.fhir.r4.model.ValueSet theValueSetToExpandR4) {
|
||||||
org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent expandedR4 = expandValueSet(theValueSetToExpandR4).getExpansion();
|
org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent expandedR4 = expandValueSet(theValueSetToExpandR4).getExpansion();
|
||||||
|
|
||||||
|
@ -507,7 +506,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expandValueSetHandleIncludeOrExclude(ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, boolean theAdd, AtomicInteger theCodeCounter) {
|
private void expandValueSetHandleIncludeOrExclude(IValueSetCodeAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, boolean theAdd, AtomicInteger theCodeCounter) {
|
||||||
String system = theInclude.getSystem();
|
String system = theInclude.getSystem();
|
||||||
boolean hasSystem = isNotBlank(system);
|
boolean hasSystem = isNotBlank(system);
|
||||||
boolean hasValueSet = theInclude.getValueSet().size() > 0;
|
boolean hasValueSet = theInclude.getValueSet().size() > 0;
|
||||||
|
@ -525,7 +524,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
* since we're going to do it without the database.
|
* since we're going to do it without the database.
|
||||||
*/
|
*/
|
||||||
if (myFulltextSearchSvc == null) {
|
if (myFulltextSearchSvc == null) {
|
||||||
expandWithoutHibernateSearch(theExpansionComponent, theAddedCodes, theInclude, system, theAdd, theCodeCounter);
|
expandWithoutHibernateSearch(theValueSetCodeAccumulator, theAddedCodes, theInclude, system, theAdd, theCodeCounter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,7 +648,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
for (Object next : jpaQuery.getResultList()) {
|
for (Object next : jpaQuery.getResultList()) {
|
||||||
count.incrementAndGet();
|
count.incrementAndGet();
|
||||||
TermConcept concept = (TermConcept) next;
|
TermConcept concept = (TermConcept) next;
|
||||||
addCodeIfNotAlreadyAdded(theExpansionComponent, theAddedCodes, concept, theAdd, theCodeCounter);
|
addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, concept, theAdd, theCodeCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -670,24 +669,21 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
if (theInclude.getConcept().isEmpty() == false) {
|
if (theInclude.getConcept().isEmpty() == false) {
|
||||||
for (ValueSet.ConceptReferenceComponent next : theInclude.getConcept()) {
|
for (ValueSet.ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||||
String nextCode = next.getCode();
|
String nextCode = next.getCode();
|
||||||
if (isNotBlank(nextCode) && !theAddedCodes.contains(nextCode)) {
|
if (isNoneBlank(system, nextCode) && !theAddedCodes.contains(system + "|" + nextCode)) {
|
||||||
CodeSystem.ConceptDefinitionComponent code = findCode(codeSystemFromContext.getConcept(), nextCode);
|
CodeSystem.ConceptDefinitionComponent code = findCode(codeSystemFromContext.getConcept(), nextCode);
|
||||||
if (code != null) {
|
if (code != null) {
|
||||||
if (theAdd && theAddedCodes.add(nextCode)) {
|
if (theAdd && theAddedCodes.add(system + "|" + nextCode)) {
|
||||||
ValueSet.ValueSetExpansionContainsComponent contains = theExpansionComponent.addContains();
|
theValueSetCodeAccumulator.includeCode(system, nextCode, code.getDisplay());
|
||||||
contains.setCode(nextCode);
|
|
||||||
contains.setSystem(system);
|
|
||||||
contains.setDisplay(code.getDisplay());
|
|
||||||
}
|
}
|
||||||
if (!theAdd && theAddedCodes.remove(nextCode)) {
|
if (!theAdd && theAddedCodes.remove(system + "|" + nextCode)) {
|
||||||
removeCodeFromExpansion(system, nextCode, theExpansionComponent);
|
theValueSetCodeAccumulator.excludeCode(system, nextCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<CodeSystem.ConceptDefinitionComponent> concept = codeSystemFromContext.getConcept();
|
List<CodeSystem.ConceptDefinitionComponent> concept = codeSystemFromContext.getConcept();
|
||||||
addConceptsToList(theExpansionComponent, theAddedCodes, system, concept, theAdd);
|
addConceptsToList(theValueSetCodeAccumulator, theAddedCodes, system, concept, theAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -702,12 +698,12 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
myConceptDao
|
myConceptDao
|
||||||
.findByCodeSystemAndCode(codeSystem.getCurrentVersion(), nextConcept.getCode())
|
.findByCodeSystemAndCode(codeSystem.getCurrentVersion(), nextConcept.getCode())
|
||||||
.ifPresent(concept ->
|
.ifPresent(concept ->
|
||||||
addCodeIfNotAlreadyAdded(theExpansionComponent, theAddedCodes, concept, theAdd, theCodeCounter)
|
addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, concept, theAdd, theCodeCounter)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!theAdd && theAddedCodes.remove(nextConcept.getCode())) {
|
if (isNoneBlank(nextConcept.getSystem(), nextConcept.getCode()) && !theAdd && theAddedCodes.remove(nextConcept.getSystem() + "|" + nextConcept.getCode())) {
|
||||||
removeCodeFromExpansion(nextConcept.getSystem(), nextConcept.getCode(), theExpansionComponent);
|
theValueSetCodeAccumulator.excludeCode(nextConcept.getSystem(), nextConcept.getCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,9 +713,11 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expandWithoutHibernateSearch(ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, String theSystem, boolean theAdd, AtomicInteger theCodeCounter) {
|
private void expandWithoutHibernateSearch(IValueSetCodeAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, String theSystem, boolean theAdd, AtomicInteger theCodeCounter) {
|
||||||
ourLog.trace("Hibernate search is not enabled");
|
ourLog.trace("Hibernate search is not enabled");
|
||||||
Validate.isTrue(theExpansionComponent.getParameter().isEmpty(), "Can not expand ValueSet with parameters - Hibernate Search is not enabled on this server.");
|
if (theValueSetCodeAccumulator instanceof ValueSetExpansionComponentWithCodeAccumulator) {
|
||||||
|
Validate.isTrue(((ValueSetExpansionComponentWithCodeAccumulator) theValueSetCodeAccumulator).getParameter().isEmpty(), "Can not expand ValueSet with parameters - Hibernate Search is not enabled on this server.");
|
||||||
|
}
|
||||||
Validate.isTrue(theInclude.getFilter().isEmpty(), "Can not expand ValueSet with filters - Hibernate Search is not enabled on this server.");
|
Validate.isTrue(theInclude.getFilter().isEmpty(), "Can not expand ValueSet with filters - Hibernate Search is not enabled on this server.");
|
||||||
Validate.isTrue(isNotBlank(theSystem), "Can not expand ValueSet without explicit system - Hibernate Search is not enabled on this server.");
|
Validate.isTrue(isNotBlank(theSystem), "Can not expand ValueSet without explicit system - Hibernate Search is not enabled on this server.");
|
||||||
|
|
||||||
|
@ -727,7 +725,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
if (!theSystem.equals(theInclude.getSystem())) {
|
if (!theSystem.equals(theInclude.getSystem())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addCodeIfNotAlreadyAdded(theExpansionComponent, theAddedCodes, null, theAdd, theCodeCounter, theSystem, next.getCode(), next.getDisplay());
|
addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, null, theAdd, theCodeCounter, theSystem, next.getCode(), next.getDisplay());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1038,14 +1036,6 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeCodeFromExpansion(String theCodeSystem, String theCode, ValueSet.ValueSetExpansionComponent theExpansionComponent) {
|
|
||||||
theExpansionComponent
|
|
||||||
.getContains()
|
|
||||||
.removeIf(t ->
|
|
||||||
theCodeSystem.equals(t.getSystem()) &&
|
|
||||||
theCode.equals(t.getCode()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private int saveConcept(TermConcept theConcept) {
|
private int saveConcept(TermConcept theConcept) {
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
|
|
||||||
|
@ -1144,7 +1134,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
List<TermCodeSystemVersion> existing = myCodeSystemVersionDao.findByCodeSystemResource(theCodeSystemResourcePid);
|
List<TermCodeSystemVersion> existing = myCodeSystemVersionDao.findByCodeSystemResource(theCodeSystemResourcePid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For now we always delete old versions.. At some point it would be nice to allow configuration to keep old versions
|
* For now we always delete old versions. At some point it would be nice to allow configuration to keep old versions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ourLog.info("Deleting old code system versions");
|
ourLog.info("Deleting old code system versions");
|
||||||
|
@ -1318,8 +1308,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
TermConceptMapGroupElement termConceptMapGroupElement;
|
TermConceptMapGroupElement termConceptMapGroupElement;
|
||||||
for (ConceptMap.SourceElementComponent element : group.getElement()) {
|
for (ConceptMap.SourceElementComponent element : group.getElement()) {
|
||||||
if (isBlank(element.getCode())) {
|
if (isBlank(element.getCode())) {
|
||||||
// FIXME: JA - send this to an interceptor message so it can be
|
// FIXME: JA - send this to an interceptor message so it can be output
|
||||||
// output
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
termConceptMapGroupElement = new TermConceptMapGroupElement();
|
termConceptMapGroupElement = new TermConceptMapGroupElement();
|
||||||
|
@ -1386,26 +1375,53 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
||||||
Optional<TermValueSet> optionalExistingTermValueSetByUrl = myValueSetDao.findByUrl(url);
|
Optional<TermValueSet> optionalExistingTermValueSetByUrl = myValueSetDao.findByUrl(url);
|
||||||
if (!optionalExistingTermValueSetByUrl.isPresent()) {
|
if (!optionalExistingTermValueSetByUrl.isPresent()) {
|
||||||
myValueSetDao.save(termValueSet);
|
myValueSetDao.save(termValueSet);
|
||||||
int codesSaved = 0;
|
int conceptsSaved = 0;
|
||||||
|
int designationsSaved = 0;
|
||||||
|
|
||||||
|
// FIXME: DM 2019-07-15 - Here we should call expandValueSet(ValueSet theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator).
|
||||||
|
// FIXME: DM 2019-07-15 - We need an implementation IValueSetCodeAccumulator that saves ValueSetConcept records and their children.
|
||||||
ValueSet expandedValueSet = expandValueSet(theValueSet);
|
ValueSet expandedValueSet = expandValueSet(theValueSet);
|
||||||
if (expandedValueSet.hasExpansion()) {
|
if (expandedValueSet.hasExpansion()) {
|
||||||
if (expandedValueSet.getExpansion().hasTotal() && expandedValueSet.getExpansion().getTotal() > 0) {
|
if (expandedValueSet.getExpansion().hasTotal() && expandedValueSet.getExpansion().getTotal() > 0) {
|
||||||
TermValueSetCode code;
|
TermValueSetConcept concept;
|
||||||
for (ValueSet.ValueSetExpansionContainsComponent contains : expandedValueSet.getExpansion().getContains()) {
|
for (ValueSet.ValueSetExpansionContainsComponent contains : expandedValueSet.getExpansion().getContains()) {
|
||||||
ValidateUtil.isNotBlankOrThrowInvalidRequest(contains.getSystem(), "ValueSet contains a code with no system value");
|
ValidateUtil.isNotBlankOrThrowInvalidRequest(contains.getSystem(), "ValueSet contains a concept with no system value");
|
||||||
ValidateUtil.isNotBlankOrThrowInvalidRequest(contains.getCode(), "ValueSet contains a code with no code value");
|
ValidateUtil.isNotBlankOrThrowInvalidRequest(contains.getCode(), "ValueSet contains a concept with no code value");
|
||||||
|
|
||||||
code = new TermValueSetCode();
|
concept = new TermValueSetConcept();
|
||||||
code.setValueSet(termValueSet);
|
concept.setValueSet(termValueSet);
|
||||||
code.setSystem(contains.getSystem());
|
concept.setSystem(contains.getSystem());
|
||||||
code.setCode(contains.getCode());
|
concept.setCode(contains.getCode());
|
||||||
code.setDisplay(contains.hasDisplay() ? contains.getDisplay() : null);
|
concept.setDisplay(contains.hasDisplay() ? contains.getDisplay() : null);
|
||||||
myValueSetCodeDao.save(code);
|
myValueSetConceptDao.save(concept);
|
||||||
|
|
||||||
if (codesSaved++ % 250 == 0) {
|
TermValueSetConceptDesignation designation;
|
||||||
ourLog.info("Have pre-expanded {} codes in ValueSet", codesSaved);
|
for (ValueSet.ConceptReferenceDesignationComponent containedDesignation : contains.getDesignation()) {
|
||||||
myValueSetCodeDao.flush();
|
ValidateUtil.isNotBlankOrThrowInvalidRequest(containedDesignation.getValue(), "ValueSet contains a concept designation with no value");
|
||||||
|
|
||||||
|
designation = new TermValueSetConceptDesignation();
|
||||||
|
designation.setConcept(concept);
|
||||||
|
designation.setLanguage(containedDesignation.hasLanguage() ? containedDesignation.getLanguage() : null);
|
||||||
|
if (containedDesignation.hasUse()) {
|
||||||
|
designation.setUseSystem(containedDesignation.getUse().hasSystem() ? containedDesignation.getUse().getSystem() : null);
|
||||||
|
designation.setUseCode(containedDesignation.getUse().hasCode() ? containedDesignation.getUse().getCode() : null);
|
||||||
|
designation.setUseDisplay(containedDesignation.getUse().hasDisplay() ? containedDesignation.getUse().getDisplay() : null);
|
||||||
|
}
|
||||||
|
designation.setValue(containedDesignation.getValue());
|
||||||
|
myValueSetConceptDesignationDao.save(designation);
|
||||||
|
|
||||||
|
if (designationsSaved++ % 250 == 0) {
|
||||||
|
ourLog.info("Have pre-expanded {} designations in ValueSet", designationsSaved);
|
||||||
|
myValueSetConceptDesignationDao.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: DM 2019-07-16 - We need TermValueSetConceptProperty, similar to TermConceptProperty.
|
||||||
|
// TODO: DM 2019-07-16 - We should also populate TermValueSetConceptProperty entities here.
|
||||||
|
|
||||||
|
if (conceptsSaved++ % 250 == 0) {
|
||||||
|
ourLog.info("Have pre-expanded {} concepts in ValueSet", conceptsSaved);
|
||||||
|
myValueSetConceptDao.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,11 @@ public class HapiTerminologySvcDstu2 extends BaseHapiTerminologySvcImpl {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void expandValueSet(IBaseResource theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VersionIndependentConcept> expandValueSet(String theValueSet) {
|
public List<VersionIndependentConcept> expandValueSet(String theValueSet) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
@ -25,8 +25,7 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
|
@ -171,6 +170,19 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvcImpl implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void expandValueSet(IBaseResource theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator) {
|
||||||
|
ValueSet valueSetToExpand = (ValueSet) theValueSetToExpand;
|
||||||
|
|
||||||
|
try {
|
||||||
|
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
|
||||||
|
valueSetToExpandR4 = VersionConvertor_30_40.convertValueSet(valueSetToExpand);
|
||||||
|
super.expandValueSet(valueSetToExpandR4, theValueSetCodeAccumulator);
|
||||||
|
} catch (FHIRException e) {
|
||||||
|
throw new InternalErrorException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VersionIndependentConcept> expandValueSet(String theValueSet) {
|
public List<VersionIndependentConcept> expandValueSet(String theValueSet) {
|
||||||
ValueSet vs = myValidationSupport.fetchResource(myContext, ValueSet.class, theValueSet);
|
ValueSet vs = myValidationSupport.fetchResource(myContext, ValueSet.class, theValueSet);
|
||||||
|
|
|
@ -131,6 +131,11 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvcImpl implements
|
||||||
return super.expandValueSet(valueSetToExpand);
|
return super.expandValueSet(valueSetToExpand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void expandValueSet(IBaseResource theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator) {
|
||||||
|
ValueSet valueSetToExpand = (ValueSet) theValueSetToExpand;
|
||||||
|
super.expandValueSet(valueSetToExpand, theValueSetCodeAccumulator);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueSetExpander.ValueSetExpansionOutcome expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
|
public ValueSetExpander.ValueSetExpansionOutcome expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
|
||||||
|
|
|
@ -41,11 +41,15 @@ public interface IHapiTerminologySvc {
|
||||||
|
|
||||||
ValueSet expandValueSet(ValueSet theValueSetToExpand);
|
ValueSet expandValueSet(ValueSet theValueSetToExpand);
|
||||||
|
|
||||||
|
void expandValueSet(ValueSet theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version independent
|
* Version independent
|
||||||
*/
|
*/
|
||||||
IBaseResource expandValueSet(IBaseResource theValueSetToExpand);
|
IBaseResource expandValueSet(IBaseResource theValueSetToExpand);
|
||||||
|
|
||||||
|
void expandValueSet(IBaseResource theValueSetToExpand, IValueSetCodeAccumulator theValueSetCodeAccumulator);
|
||||||
|
|
||||||
List<VersionIndependentConcept> expandValueSet(String theValueSet);
|
List<VersionIndependentConcept> expandValueSet(String theValueSet);
|
||||||
|
|
||||||
Optional<TermConcept> findCode(String theCodeSystem, String theCode);
|
Optional<TermConcept> findCode(String theCodeSystem, String theCode);
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2019 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.entity.TermConceptDesignation;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface IValueSetCodeAccumulator {
|
||||||
|
|
||||||
|
void includeCode(String theSystem, String theCode, String theDisplay);
|
||||||
|
|
||||||
|
void includeCodeWithDesignations(String theSystem, String theCode, String theDisplay, Collection<TermConceptDesignation> theDesignations);
|
||||||
|
|
||||||
|
void excludeCode(String theSystem, String theCode);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2019 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.entity.TermConceptDesignation;
|
||||||
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class ValueSetExpansionComponentWithCodeAccumulator extends ValueSet.ValueSetExpansionComponent implements IValueSetCodeAccumulator {
|
||||||
|
@Override
|
||||||
|
public void includeCode(String theSystem, String theCode, String theDisplay) {
|
||||||
|
ValueSet.ValueSetExpansionContainsComponent contains = this.addContains();
|
||||||
|
contains.setSystem(theSystem);
|
||||||
|
contains.setCode(theCode);
|
||||||
|
contains.setDisplay(theDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void includeCodeWithDesignations(String theSystem, String theCode, String theDisplay, Collection<TermConceptDesignation> theDesignations) {
|
||||||
|
ValueSet.ValueSetExpansionContainsComponent contains = this.addContains();
|
||||||
|
contains.setSystem(theSystem);
|
||||||
|
contains.setCode(theCode);
|
||||||
|
contains.setDisplay(theDisplay);
|
||||||
|
if (theDesignations != null) {
|
||||||
|
for (TermConceptDesignation termConceptDesignation : theDesignations) {
|
||||||
|
contains
|
||||||
|
.addDesignation()
|
||||||
|
.setValue(termConceptDesignation.getValue())
|
||||||
|
.setLanguage(termConceptDesignation.getLanguage())
|
||||||
|
.getUse()
|
||||||
|
.setSystem(termConceptDesignation.getUseSystem())
|
||||||
|
.setCode(termConceptDesignation.getUseCode())
|
||||||
|
.setDisplay(termConceptDesignation.getUseDisplay());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void excludeCode(String theSystem, String theCode) {
|
||||||
|
this
|
||||||
|
.getContains()
|
||||||
|
.removeIf(t ->
|
||||||
|
theSystem.equals(t.getSystem()) &&
|
||||||
|
theCode.equals(t.getCode()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,6 @@ import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
|
||||||
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
||||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||||
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
import ca.uhn.fhir.jpa.subscription.SubscriptionInterceptorLoader;
|
|
||||||
import ca.uhn.fhir.jpa.term.BaseHapiTerminologySvcImpl;
|
import ca.uhn.fhir.jpa.term.BaseHapiTerminologySvcImpl;
|
||||||
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;
|
||||||
|
@ -27,7 +26,6 @@ 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.exceptions.InternalErrorException;
|
||||||
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;
|
||||||
|
@ -59,7 +57,6 @@ import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes = {TestDstu3Config.class})
|
@ContextConfiguration(classes = {TestDstu3Config.class})
|
||||||
|
@ -240,6 +237,10 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
@Qualifier("myTaskDaoDstu3")
|
@Qualifier("myTaskDaoDstu3")
|
||||||
protected IFhirResourceDao<Task> myTaskDao;
|
protected IFhirResourceDao<Task> myTaskDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
protected ITermConceptDao myTermConceptDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermCodeSystemDao myTermCodeSystemDao;
|
||||||
|
@Autowired
|
||||||
protected IHapiTerminologySvc myTermSvc;
|
protected IHapiTerminologySvc myTermSvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected PlatformTransactionManager myTransactionMgr;
|
protected PlatformTransactionManager myTransactionMgr;
|
||||||
|
|
|
@ -130,6 +130,8 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermConceptDao myTermConceptDao;
|
protected ITermConceptDao myTermConceptDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
protected ITermConceptDesignationDao myTermConceptDesignationDao;
|
||||||
|
@Autowired
|
||||||
@Qualifier("myConditionDaoR4")
|
@Qualifier("myConditionDaoR4")
|
||||||
protected IFhirResourceDao<Condition> myConditionDao;
|
protected IFhirResourceDao<Condition> myConditionDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -293,7 +295,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermValueSetDao myTermValueSetDao;
|
protected ITermValueSetDao myTermValueSetDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermValueSetCodeDao myTermValueSetCodeDao;
|
protected ITermValueSetConceptDao myTermValueSetConceptDao;
|
||||||
|
@Autowired
|
||||||
|
protected ITermValueSetConceptDesignationDao myTermValueSetConceptDesignationDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ITermConceptMapDao myTermConceptMapDao;
|
protected ITermConceptMapDao myTermConceptMapDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package ca.uhn.fhir.jpa.term;
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.dstu3.BaseJpaDstu3Test;
|
import ca.uhn.fhir.jpa.dao.dstu3.BaseJpaDstu3Test;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
||||||
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
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.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
@ -19,7 +19,11 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -30,11 +34,13 @@ import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(TerminologySvcImplDstu3Test.class);
|
||||||
|
|
||||||
private static final String CS_URL = "http://example.com/my_code_system";
|
private static final String CS_URL = "http://example.com/my_code_system";
|
||||||
private static final String CS_URL_2 = "http://example.com/my_code_system2";
|
private static final String CS_URL_2 = "http://example.com/my_code_system2";
|
||||||
@Autowired
|
|
||||||
private ITermCodeSystemDao myTermCodeSystemDao;
|
private IIdType myExtensionalCsId;
|
||||||
|
private IIdType myExtensionalVsId;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void after() {
|
public void after() {
|
||||||
|
@ -76,6 +82,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
||||||
childAAB.addPropertyString("propA", "valueAAB");
|
childAAB.addPropertyString("propA", "valueAAB");
|
||||||
childAAB.addPropertyString("propB", "foo");
|
childAAB.addPropertyString("propB", "foo");
|
||||||
childAAB.addDesignation()
|
childAAB.addDesignation()
|
||||||
|
.setLanguage("D1L")
|
||||||
.setUseSystem("D1S")
|
.setUseSystem("D1S")
|
||||||
.setUseCode("D1C")
|
.setUseCode("D1C")
|
||||||
.setUseDisplay("D1D")
|
.setUseDisplay("D1D")
|
||||||
|
@ -546,13 +553,13 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
||||||
assertEquals("childAAB", concept.getCode());
|
assertEquals("childAAB", concept.getCode());
|
||||||
assertEquals("http://example.com/my_code_system", concept.getSystem());
|
assertEquals("http://example.com/my_code_system", concept.getSystem());
|
||||||
assertEquals(null, concept.getDisplay());
|
assertEquals(null, concept.getDisplay());
|
||||||
|
assertEquals("D1L", concept.getDesignation().get(0).getLanguage());
|
||||||
assertEquals("D1S", concept.getDesignation().get(0).getUse().getSystem());
|
assertEquals("D1S", concept.getDesignation().get(0).getUse().getSystem());
|
||||||
assertEquals("D1C", concept.getDesignation().get(0).getUse().getCode());
|
assertEquals("D1C", concept.getDesignation().get(0).getUse().getCode());
|
||||||
assertEquals("D1D", concept.getDesignation().get(0).getUse().getDisplay());
|
assertEquals("D1D", concept.getDesignation().get(0).getUse().getDisplay());
|
||||||
assertEquals("D1V", concept.getDesignation().get(0).getValue());
|
assertEquals("D1V", concept.getDesignation().get(0).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStoreCodeSystemInvalidCyclicLoop() {
|
public void testStoreCodeSystemInvalidCyclicLoop() {
|
||||||
CodeSystem codeSystem = new CodeSystem();
|
CodeSystem codeSystem = new CodeSystem();
|
||||||
|
@ -585,6 +592,103 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreTermCodeSystemAndNestedChildren() {
|
||||||
|
IIdType codeSystemId = createCodeSystem();
|
||||||
|
CodeSystem codeSystemResource = myCodeSystemDao.read(codeSystemId);
|
||||||
|
ourLog.info("CodeSystem:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystemResource));
|
||||||
|
|
||||||
|
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
|
||||||
|
TermCodeSystem codeSystem = myTermCodeSystemDao.findByResourcePid(codeSystemId.getIdPartAsLong());
|
||||||
|
assertEquals(CS_URL, codeSystem.getCodeSystemUri());
|
||||||
|
assertEquals("SYSTEM NAME", codeSystem.getName());
|
||||||
|
|
||||||
|
TermCodeSystemVersion codeSystemVersion = codeSystem.getCurrentVersion();
|
||||||
|
assertEquals(9, codeSystemVersion.getConcepts().size());
|
||||||
|
|
||||||
|
List<TermConcept> concepts = myTermConceptDao.findByCodeSystemVersion(codeSystemVersion);
|
||||||
|
|
||||||
|
TermConcept parentWithNoChildrenA = concepts.get(0);
|
||||||
|
assertEquals("ParentWithNoChildrenA", parentWithNoChildrenA.getCode());
|
||||||
|
assertNull(parentWithNoChildrenA.getDisplay());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getChildren().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getParents().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getDesignations().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentWithNoChildrenB = concepts.get(1);
|
||||||
|
assertEquals("ParentWithNoChildrenB", parentWithNoChildrenB.getCode());
|
||||||
|
assertNull(parentWithNoChildrenB.getDisplay());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getChildren().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getParents().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getDesignations().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentWithNoChildrenC = concepts.get(2);
|
||||||
|
assertEquals("ParentWithNoChildrenC", parentWithNoChildrenC.getCode());
|
||||||
|
assertNull(parentWithNoChildrenC.getDisplay());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getChildren().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getParents().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getDesignations().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentA = concepts.get(3);
|
||||||
|
assertEquals("ParentA", parentA.getCode());
|
||||||
|
assertNull(parentA.getDisplay());
|
||||||
|
assertEquals(2, parentA.getChildren().size());
|
||||||
|
assertEquals(0, parentA.getParents().size());
|
||||||
|
assertEquals(0, parentA.getDesignations().size());
|
||||||
|
assertEquals(0, parentA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAA = concepts.get(4);
|
||||||
|
assertEquals("childAA", childAA.getCode());
|
||||||
|
assertNull(childAA.getDisplay());
|
||||||
|
assertEquals(2, childAA.getChildren().size());
|
||||||
|
assertEquals(1, childAA.getParents().size());
|
||||||
|
assertSame(parentA, childAA.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(0, childAA.getDesignations().size());
|
||||||
|
assertEquals(0, childAA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAAA = concepts.get(5);
|
||||||
|
assertEquals("childAAA", childAAA.getCode());
|
||||||
|
assertNull(childAAA.getDisplay());
|
||||||
|
assertEquals(0, childAAA.getChildren().size());
|
||||||
|
assertEquals(1, childAAA.getParents().size());
|
||||||
|
assertSame(childAA, childAAA.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(0, childAAA.getDesignations().size());
|
||||||
|
assertEquals(2, childAAA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAAB = concepts.get(6);
|
||||||
|
assertEquals("childAAB", childAAB.getCode());
|
||||||
|
assertNull(childAAB.getDisplay());
|
||||||
|
assertEquals(0, childAAB.getChildren().size());
|
||||||
|
assertEquals(1, childAAB.getParents().size());
|
||||||
|
assertSame(childAA, childAAB.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(1, childAAB.getDesignations().size());
|
||||||
|
assertEquals(2, childAAB.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAB = concepts.get(7);
|
||||||
|
assertEquals("childAB", childAB.getCode());
|
||||||
|
assertNull(childAB.getDisplay());
|
||||||
|
assertEquals(0, childAB.getChildren().size());
|
||||||
|
assertEquals(1, childAB.getParents().size());
|
||||||
|
assertSame(parentA, childAB.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(0, childAB.getDesignations().size());
|
||||||
|
assertEquals(0, childAB.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentB = concepts.get(8);
|
||||||
|
assertEquals("ParentB", parentB.getCode());
|
||||||
|
assertNull(parentB.getDisplay());
|
||||||
|
assertEquals(0, parentB.getChildren().size());
|
||||||
|
assertEquals(0, parentB.getParents().size());
|
||||||
|
assertEquals(0, parentB.getDesignations().size());
|
||||||
|
assertEquals(0, parentB.getProperties().size());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that a custom ValueSet against a custom CodeSystem expands correctly
|
* Check that a custom ValueSet against a custom CodeSystem expands correctly
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.term;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
|
import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
|
||||||
import ca.uhn.fhir.jpa.entity.*;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
@ -10,6 +11,7 @@ import org.hl7.fhir.r4.model.*;
|
||||||
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
|
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
@ -21,6 +23,9 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(TerminologySvcImplR4Test.class);
|
private static final Logger ourLog = LoggerFactory.getLogger(TerminologySvcImplR4Test.class);
|
||||||
|
@ -30,6 +35,9 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
||||||
private IIdType myExtensionalCsId;
|
private IIdType myExtensionalCsId;
|
||||||
private IIdType myExtensionalVsId;
|
private IIdType myExtensionalVsId;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
IValueSetCodeAccumulator myValueSetCodeAccumulator;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
myDaoConfig.setAllowExternalReferences(true);
|
myDaoConfig.setAllowExternalReferences(true);
|
||||||
|
@ -41,6 +49,57 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
||||||
myDaoConfig.setPreExpandValueSetsExperimental(new DaoConfig().isPreExpandValueSetsExperimental());
|
myDaoConfig.setPreExpandValueSetsExperimental(new DaoConfig().isPreExpandValueSetsExperimental());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IIdType createCodeSystem() {
|
||||||
|
CodeSystem codeSystem = new CodeSystem();
|
||||||
|
codeSystem.setUrl(CS_URL);
|
||||||
|
codeSystem.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT);
|
||||||
|
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
|
||||||
|
|
||||||
|
ResourceTable table = myResourceTableDao.findById(id.getIdPartAsLong()).orElseThrow(IllegalArgumentException::new);
|
||||||
|
|
||||||
|
TermCodeSystemVersion cs = new TermCodeSystemVersion();
|
||||||
|
cs.setResource(table);
|
||||||
|
|
||||||
|
TermConcept parent;
|
||||||
|
parent = new TermConcept(cs, "ParentWithNoChildrenA");
|
||||||
|
cs.getConcepts().add(parent);
|
||||||
|
parent = new TermConcept(cs, "ParentWithNoChildrenB");
|
||||||
|
cs.getConcepts().add(parent);
|
||||||
|
parent = new TermConcept(cs, "ParentWithNoChildrenC");
|
||||||
|
cs.getConcepts().add(parent);
|
||||||
|
|
||||||
|
TermConcept parentA = new TermConcept(cs, "ParentA");
|
||||||
|
cs.getConcepts().add(parentA);
|
||||||
|
|
||||||
|
TermConcept childAA = new TermConcept(cs, "childAA");
|
||||||
|
parentA.addChild(childAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
|
||||||
|
|
||||||
|
TermConcept childAAA = new TermConcept(cs, "childAAA");
|
||||||
|
childAAA.addPropertyString("propA", "valueAAA");
|
||||||
|
childAAA.addPropertyString("propB", "foo");
|
||||||
|
childAA.addChild(childAAA, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
|
||||||
|
|
||||||
|
TermConcept childAAB = new TermConcept(cs, "childAAB");
|
||||||
|
childAAB.addPropertyString("propA", "valueAAB");
|
||||||
|
childAAB.addPropertyString("propB", "foo");
|
||||||
|
childAAB.addDesignation()
|
||||||
|
.setUseSystem("D1S")
|
||||||
|
.setUseCode("D1C")
|
||||||
|
.setUseDisplay("D1D")
|
||||||
|
.setValue("D1V");
|
||||||
|
childAA.addChild(childAAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
|
||||||
|
|
||||||
|
TermConcept childAB = new TermConcept(cs, "childAB");
|
||||||
|
parentA.addChild(childAB, TermConceptParentChildLink.RelationshipTypeEnum.ISA);
|
||||||
|
|
||||||
|
TermConcept parentB = new TermConcept(cs, "ParentB");
|
||||||
|
cs.getConcepts().add(parentB);
|
||||||
|
|
||||||
|
myTermSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", cs);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
private void createAndPersistConceptMap() {
|
private void createAndPersistConceptMap() {
|
||||||
ConceptMap conceptMap = createConceptMap();
|
ConceptMap conceptMap = createConceptMap();
|
||||||
persistConceptMap(conceptMap);
|
persistConceptMap(conceptMap);
|
||||||
|
@ -60,11 +119,21 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
||||||
loadAndPersistValueSet();
|
loadAndPersistValueSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadAndPersistCodeSystemAndValueSetWithDesignations() throws IOException {
|
||||||
|
loadAndPersistCodeSystemWithDesignations();
|
||||||
|
loadAndPersistValueSet();
|
||||||
|
}
|
||||||
|
|
||||||
private void loadAndPersistCodeSystem() throws IOException {
|
private void loadAndPersistCodeSystem() throws IOException {
|
||||||
CodeSystem codeSystem = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs.xml");
|
CodeSystem codeSystem = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs.xml");
|
||||||
persistCodeSystem(codeSystem);
|
persistCodeSystem(codeSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadAndPersistCodeSystemWithDesignations() throws IOException {
|
||||||
|
CodeSystem codeSystem = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs-with-designations.xml");
|
||||||
|
persistCodeSystem(codeSystem);
|
||||||
|
}
|
||||||
|
|
||||||
private void persistCodeSystem(CodeSystem theCodeSystem) {
|
private void persistCodeSystem(CodeSystem theCodeSystem) {
|
||||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -202,6 +271,173 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
||||||
loadAndPersistValueSet();
|
loadAndPersistValueSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandValueSetWithValueSetCodeAccumulator() {
|
||||||
|
createCodeSystem();
|
||||||
|
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
ValueSet.ConceptSetComponent include = vs.getCompose().addInclude();
|
||||||
|
include.setSystem(CS_URL);
|
||||||
|
|
||||||
|
myTermSvc.expandValueSet(vs, myValueSetCodeAccumulator);
|
||||||
|
verify(myValueSetCodeAccumulator, times(9)).includeCodeWithDesignations(anyString(), anyString(), nullable(String.class), anyCollection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreTermCodeSystemAndChildren() throws Exception {
|
||||||
|
loadAndPersistCodeSystemWithDesignations();
|
||||||
|
|
||||||
|
CodeSystem codeSystem = myCodeSystemDao.read(myExtensionalCsId);
|
||||||
|
ourLog.info("CodeSystem:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem));
|
||||||
|
|
||||||
|
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
|
||||||
|
TermCodeSystem codeSystem = myTermCodeSystemDao.findByResourcePid(myExtensionalCsId.getIdPartAsLong());
|
||||||
|
assertEquals("http://acme.org", codeSystem.getCodeSystemUri());
|
||||||
|
assertNull(codeSystem.getName());
|
||||||
|
|
||||||
|
TermCodeSystemVersion codeSystemVersion = codeSystem.getCurrentVersion();
|
||||||
|
assertEquals(24, codeSystemVersion.getConcepts().size());
|
||||||
|
|
||||||
|
List<TermConcept> concepts = myTermConceptDao.findByCodeSystemVersion(codeSystemVersion);
|
||||||
|
|
||||||
|
TermConcept concept = concepts.get(0);
|
||||||
|
assertEquals("8450-9", concept.getCode());
|
||||||
|
assertEquals("Systolic blood pressure--expiration", concept.getDisplay());
|
||||||
|
assertEquals(1, concept.getDesignations().size());
|
||||||
|
|
||||||
|
TermConceptDesignation designation = concept.getDesignations().iterator().next();
|
||||||
|
assertEquals("nl", designation.getLanguage());
|
||||||
|
assertEquals("http://snomed.info/sct", designation.getUseSystem());
|
||||||
|
assertEquals("900000000000013009", designation.getUseCode());
|
||||||
|
assertEquals("Synonym", designation.getUseDisplay());
|
||||||
|
assertEquals("Systolische bloeddruk - expiratie", designation.getValue());
|
||||||
|
|
||||||
|
concept = concepts.get(1);
|
||||||
|
assertEquals("11378-7", concept.getCode());
|
||||||
|
assertEquals("Systolic blood pressure at First encounter", concept.getDisplay());
|
||||||
|
assertEquals(0, concept.getDesignations().size());
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
concept = concepts.get(22);
|
||||||
|
assertEquals("8491-3", concept.getCode());
|
||||||
|
assertEquals("Systolic blood pressure 1 hour minimum", concept.getDisplay());
|
||||||
|
assertEquals(1, concept.getDesignations().size());
|
||||||
|
|
||||||
|
designation = concept.getDesignations().iterator().next();
|
||||||
|
assertEquals("nl", designation.getLanguage());
|
||||||
|
assertEquals("http://snomed.info/sct", designation.getUseSystem());
|
||||||
|
assertEquals("900000000000013009", designation.getUseCode());
|
||||||
|
assertEquals("Synonym", designation.getUseDisplay());
|
||||||
|
assertEquals("Systolische bloeddruk minimaal 1 uur", designation.getValue());
|
||||||
|
|
||||||
|
concept = concepts.get(23);
|
||||||
|
assertEquals("8492-1", concept.getCode());
|
||||||
|
assertEquals("Systolic blood pressure 8 hour minimum", concept.getDisplay());
|
||||||
|
assertEquals(0, concept.getDesignations().size());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoreTermCodeSystemAndNestedChildren() {
|
||||||
|
IIdType codeSystemId = createCodeSystem();
|
||||||
|
CodeSystem codeSystemResource = myCodeSystemDao.read(codeSystemId);
|
||||||
|
ourLog.info("CodeSystem:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystemResource));
|
||||||
|
|
||||||
|
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
|
||||||
|
TermCodeSystem codeSystem = myTermCodeSystemDao.findByResourcePid(codeSystemId.getIdPartAsLong());
|
||||||
|
assertEquals(CS_URL, codeSystem.getCodeSystemUri());
|
||||||
|
assertEquals("SYSTEM NAME", codeSystem.getName());
|
||||||
|
|
||||||
|
TermCodeSystemVersion codeSystemVersion = codeSystem.getCurrentVersion();
|
||||||
|
assertEquals(9, codeSystemVersion.getConcepts().size());
|
||||||
|
|
||||||
|
List<TermConcept> concepts = myTermConceptDao.findByCodeSystemVersion(codeSystemVersion);
|
||||||
|
|
||||||
|
TermConcept parentWithNoChildrenA = concepts.get(0);
|
||||||
|
assertEquals("ParentWithNoChildrenA", parentWithNoChildrenA.getCode());
|
||||||
|
assertNull(parentWithNoChildrenA.getDisplay());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getChildren().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getParents().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getDesignations().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentWithNoChildrenB = concepts.get(1);
|
||||||
|
assertEquals("ParentWithNoChildrenB", parentWithNoChildrenB.getCode());
|
||||||
|
assertNull(parentWithNoChildrenB.getDisplay());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getChildren().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getParents().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getDesignations().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenB.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentWithNoChildrenC = concepts.get(2);
|
||||||
|
assertEquals("ParentWithNoChildrenC", parentWithNoChildrenC.getCode());
|
||||||
|
assertNull(parentWithNoChildrenC.getDisplay());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getChildren().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getParents().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getDesignations().size());
|
||||||
|
assertEquals(0, parentWithNoChildrenC.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentA = concepts.get(3);
|
||||||
|
assertEquals("ParentA", parentA.getCode());
|
||||||
|
assertNull(parentA.getDisplay());
|
||||||
|
assertEquals(2, parentA.getChildren().size());
|
||||||
|
assertEquals(0, parentA.getParents().size());
|
||||||
|
assertEquals(0, parentA.getDesignations().size());
|
||||||
|
assertEquals(0, parentA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAA = concepts.get(4);
|
||||||
|
assertEquals("childAA", childAA.getCode());
|
||||||
|
assertNull(childAA.getDisplay());
|
||||||
|
assertEquals(2, childAA.getChildren().size());
|
||||||
|
assertEquals(1, childAA.getParents().size());
|
||||||
|
assertSame(parentA, childAA.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(0, childAA.getDesignations().size());
|
||||||
|
assertEquals(0, childAA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAAA = concepts.get(5);
|
||||||
|
assertEquals("childAAA", childAAA.getCode());
|
||||||
|
assertNull(childAAA.getDisplay());
|
||||||
|
assertEquals(0, childAAA.getChildren().size());
|
||||||
|
assertEquals(1, childAAA.getParents().size());
|
||||||
|
assertSame(childAA, childAAA.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(0, childAAA.getDesignations().size());
|
||||||
|
assertEquals(2, childAAA.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAAB = concepts.get(6);
|
||||||
|
assertEquals("childAAB", childAAB.getCode());
|
||||||
|
assertNull(childAAB.getDisplay());
|
||||||
|
assertEquals(0, childAAB.getChildren().size());
|
||||||
|
assertEquals(1, childAAB.getParents().size());
|
||||||
|
assertSame(childAA, childAAB.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(1, childAAB.getDesignations().size());
|
||||||
|
assertEquals(2, childAAB.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept childAB = concepts.get(7);
|
||||||
|
assertEquals("childAB", childAB.getCode());
|
||||||
|
assertNull(childAB.getDisplay());
|
||||||
|
assertEquals(0, childAB.getChildren().size());
|
||||||
|
assertEquals(1, childAB.getParents().size());
|
||||||
|
assertSame(parentA, childAB.getParents().iterator().next().getParent());
|
||||||
|
assertEquals(0, childAB.getDesignations().size());
|
||||||
|
assertEquals(0, childAB.getProperties().size());
|
||||||
|
|
||||||
|
TermConcept parentB = concepts.get(8);
|
||||||
|
assertEquals("ParentB", parentB.getCode());
|
||||||
|
assertNull(parentB.getDisplay());
|
||||||
|
assertEquals(0, parentB.getChildren().size());
|
||||||
|
assertEquals(0, parentB.getParents().size());
|
||||||
|
assertEquals(0, parentB.getDesignations().size());
|
||||||
|
assertEquals(0, parentB.getProperties().size());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStoreTermConceptMapAndChildren() {
|
public void testStoreTermConceptMapAndChildren() {
|
||||||
createAndPersistConceptMap();
|
createAndPersistConceptMap();
|
||||||
|
@ -384,7 +620,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
||||||
public void testStoreTermValueSetAndChildren() throws Exception {
|
public void testStoreTermValueSetAndChildren() throws Exception {
|
||||||
myDaoConfig.setPreExpandValueSetsExperimental(true);
|
myDaoConfig.setPreExpandValueSetsExperimental(true);
|
||||||
|
|
||||||
loadAndPersistCodeSystemAndValueSet();
|
loadAndPersistCodeSystemAndValueSetWithDesignations();
|
||||||
|
|
||||||
CodeSystem codeSystem = myCodeSystemDao.read(myExtensionalCsId);
|
CodeSystem codeSystem = myCodeSystemDao.read(myExtensionalCsId);
|
||||||
ourLog.info("CodeSystem:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem));
|
ourLog.info("CodeSystem:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(codeSystem));
|
||||||
|
@ -406,33 +642,51 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
||||||
ourLog.info("ValueSet:\n" + valueSet.toString());
|
ourLog.info("ValueSet:\n" + valueSet.toString());
|
||||||
assertEquals("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", valueSet.getUrl());
|
assertEquals("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2", valueSet.getUrl());
|
||||||
assertEquals("Terminology Services Connectation #1 Extensional case #2", valueSet.getName());
|
assertEquals("Terminology Services Connectation #1 Extensional case #2", valueSet.getName());
|
||||||
assertEquals(codeSystem.getConcept().size(), valueSet.getCodes().size());
|
assertEquals(codeSystem.getConcept().size(), valueSet.getConcepts().size());
|
||||||
|
|
||||||
TermValueSetCode code = valueSet.getCodes().get(0);
|
TermValueSetConcept concept = valueSet.getConcepts().get(0);
|
||||||
ourLog.info("Code:\n" + code.toString());
|
ourLog.info("Code:\n" + concept.toString());
|
||||||
assertEquals("http://acme.org", code.getSystem());
|
assertEquals("http://acme.org", concept.getSystem());
|
||||||
assertEquals("8450-9", code.getCode());
|
assertEquals("8450-9", concept.getCode());
|
||||||
assertEquals("Systolic blood pressure--expiration", code.getDisplay());
|
assertEquals("Systolic blood pressure--expiration", concept.getDisplay());
|
||||||
|
assertEquals(1, concept.getDesignations().size());
|
||||||
|
|
||||||
code = valueSet.getCodes().get(1);
|
TermValueSetConceptDesignation designation = concept.getDesignations().get(0);
|
||||||
ourLog.info("Code:\n" + code.toString());
|
assertEquals("nl", designation.getLanguage());
|
||||||
assertEquals("http://acme.org", code.getSystem());
|
assertEquals("http://snomed.info/sct", designation.getUseSystem());
|
||||||
assertEquals("11378-7", code.getCode());
|
assertEquals("900000000000013009", designation.getUseCode());
|
||||||
assertEquals("Systolic blood pressure at First encounter", code.getDisplay());
|
assertEquals("Synonym", designation.getUseDisplay());
|
||||||
|
assertEquals("Systolische bloeddruk - expiratie", designation.getValue());
|
||||||
|
|
||||||
|
concept = valueSet.getConcepts().get(1);
|
||||||
|
ourLog.info("Code:\n" + concept.toString());
|
||||||
|
assertEquals("http://acme.org", concept.getSystem());
|
||||||
|
assertEquals("11378-7", concept.getCode());
|
||||||
|
assertEquals("Systolic blood pressure at First encounter", concept.getDisplay());
|
||||||
|
assertEquals(0, concept.getDesignations().size());
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
code = valueSet.getCodes().get(22);
|
concept = valueSet.getConcepts().get(22);
|
||||||
ourLog.info("Code:\n" + code.toString());
|
ourLog.info("Code:\n" + concept.toString());
|
||||||
assertEquals("http://acme.org", code.getSystem());
|
assertEquals("http://acme.org", concept.getSystem());
|
||||||
assertEquals("8491-3", code.getCode());
|
assertEquals("8491-3", concept.getCode());
|
||||||
assertEquals("Systolic blood pressure 1 hour minimum", code.getDisplay());
|
assertEquals("Systolic blood pressure 1 hour minimum", concept.getDisplay());
|
||||||
|
assertEquals(1, concept.getDesignations().size());
|
||||||
|
|
||||||
code = valueSet.getCodes().get(23);
|
designation = concept.getDesignations().get(0);
|
||||||
ourLog.info("Code:\n" + code.toString());
|
assertEquals("nl", designation.getLanguage());
|
||||||
assertEquals("http://acme.org", code.getSystem());
|
assertEquals("http://snomed.info/sct", designation.getUseSystem());
|
||||||
assertEquals("8492-1", code.getCode());
|
assertEquals("900000000000013009", designation.getUseCode());
|
||||||
assertEquals("Systolic blood pressure 8 hour minimum", code.getDisplay());
|
assertEquals("Synonym", designation.getUseDisplay());
|
||||||
|
assertEquals("Systolische bloeddruk minimaal 1 uur", designation.getValue());
|
||||||
|
|
||||||
|
concept = valueSet.getConcepts().get(23);
|
||||||
|
ourLog.info("Code:\n" + concept.toString());
|
||||||
|
assertEquals("http://acme.org", concept.getSystem());
|
||||||
|
assertEquals("8492-1", concept.getCode());
|
||||||
|
assertEquals("Systolic blood pressure 8 hour minimum", concept.getDisplay());
|
||||||
|
assertEquals(0, concept.getDesignations().size());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
<CodeSystem xmlns="http://hl7.org/fhir">
|
||||||
|
<url value="http://acme.org" />
|
||||||
|
<concept>
|
||||||
|
<code value="8450-9" />
|
||||||
|
<display value="Systolic blood pressure--expiration" />
|
||||||
|
<designation>
|
||||||
|
<language value="nl"/>
|
||||||
|
<use>
|
||||||
|
<system value="http://snomed.info/sct"/>
|
||||||
|
<code value="900000000000013009"/>
|
||||||
|
<display value="Synonym"/>
|
||||||
|
</use>
|
||||||
|
<value value="Systolische bloeddruk - expiratie"/>
|
||||||
|
</designation>
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="11378-7" />
|
||||||
|
<display value="Systolic blood pressure at First encounter" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8493-9" />
|
||||||
|
<display value="Systolic blood pressure 10 hour minimum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8494-7" />
|
||||||
|
<display value="Systolic blood pressure 12 hour minimum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8495-4" />
|
||||||
|
<display value="Systolic blood pressure 24 hour minimum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8451-7" />
|
||||||
|
<display value="Systolic blood pressure--inspiration" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8452-5" />
|
||||||
|
<display value="Systolic blood pressure.inspiration - expiration" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8459-0" />
|
||||||
|
<display value="Systolic blood pressure--sitting" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8460-8" />
|
||||||
|
<display value="Systolic blood pressure--standing" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8461-6" />
|
||||||
|
<display value="Systolic blood pressure--supine" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8479-8" />
|
||||||
|
<display value="Systolic blood pressure by palpation" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8480-6" />
|
||||||
|
<display value="Systolic blood pressure" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8481-4" />
|
||||||
|
<display value="Systolic blood pressure 1 hour maximum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8482-2" />
|
||||||
|
<display value="Systolic blood pressure 8 hour maximum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8483-0" />
|
||||||
|
<display value="Systolic blood pressure 10 hour maximum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8484-8" />
|
||||||
|
<display value="Systolic blood pressure 12 hour maximum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8485-5" />
|
||||||
|
<display value="Systolic blood pressure 24 hour maximum" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8486-3" />
|
||||||
|
<display value="Systolic blood pressure 1 hour mean" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8487-1" />
|
||||||
|
<display value="Systolic blood pressure 8 hour mean" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8488-9" />
|
||||||
|
<display value="Systolic blood pressure 10 hour mean" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8489-7" />
|
||||||
|
<display value="Systolic blood pressure 12 hour mean" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8490-5" />
|
||||||
|
<display value="Systolic blood pressure 24 hour mean" />
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8491-3" />
|
||||||
|
<display value="Systolic blood pressure 1 hour minimum" />
|
||||||
|
<designation>
|
||||||
|
<language value="nl"/>
|
||||||
|
<use>
|
||||||
|
<system value="http://snomed.info/sct"/>
|
||||||
|
<code value="900000000000013009"/>
|
||||||
|
<display value="Synonym"/>
|
||||||
|
</use>
|
||||||
|
<value value="Systolische bloeddruk minimaal 1 uur"/>
|
||||||
|
</designation>
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="8492-1" />
|
||||||
|
<display value="Systolic blood pressure 8 hour minimum" />
|
||||||
|
</concept>
|
||||||
|
</CodeSystem>
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.migrate.tasks;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
import ca.uhn.fhir.jpa.entity.TermValueSet;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermValueSetConceptDesignation;
|
||||||
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
|
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
|
||||||
import ca.uhn.fhir.jpa.migrate.taskdef.AddColumnTask;
|
import ca.uhn.fhir.jpa.migrate.taskdef.AddColumnTask;
|
||||||
import ca.uhn.fhir.jpa.migrate.taskdef.ArbitrarySqlTask;
|
import ca.uhn.fhir.jpa.migrate.taskdef.ArbitrarySqlTask;
|
||||||
|
@ -96,23 +97,43 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
|
||||||
.references("HFJ_RESOURCE", "RES_ID");
|
.references("HFJ_RESOURCE", "RES_ID");
|
||||||
termValueSetTable.addColumn("NAME").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSet.MAX_NAME_LENGTH);
|
termValueSetTable.addColumn("NAME").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSet.MAX_NAME_LENGTH);
|
||||||
|
|
||||||
// TermValueSetCode
|
// TermValueSetConcept
|
||||||
version.startSectionWithMessage("Processing table: TRM_VALUESET_CODE");
|
version.startSectionWithMessage("Processing table: TRM_VALUESET_CONCEPT");
|
||||||
version.addIdGenerator("SEQ_VALUESET_CODE_PID");
|
version.addIdGenerator("SEQ_VALUESET_CONCEPT_PID");
|
||||||
Builder.BuilderAddTableByColumns termValueSetCodeTable = version.addTableByColumns("TRM_VALUESET_CODE", "PID");
|
Builder.BuilderAddTableByColumns termValueSetConceptTable = version.addTableByColumns("TRM_VALUESET_CONCEPT", "PID");
|
||||||
termValueSetCodeTable.addColumn("PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
|
termValueSetConceptTable.addColumn("PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
|
||||||
termValueSetCodeTable.addColumn("VALUESET_PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
|
termValueSetConceptTable.addColumn("VALUESET_PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
|
||||||
termValueSetCodeTable
|
termValueSetConceptTable
|
||||||
.addForeignKey("FK_TRM_VALUESET_PID")
|
.addForeignKey("FK_TRM_VALUESET_PID")
|
||||||
.toColumn("VALUESET_PID")
|
.toColumn("VALUESET_PID")
|
||||||
.references("TRM_VALUESET", "PID");
|
.references("TRM_VALUESET", "PID");
|
||||||
termValueSetCodeTable.addColumn("SYSTEM").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermCodeSystem.MAX_URL_LENGTH);
|
termValueSetConceptTable.addColumn("SYSTEM").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermCodeSystem.MAX_URL_LENGTH);
|
||||||
termValueSetCodeTable.addColumn("CODE").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermConcept.MAX_CODE_LENGTH);
|
termValueSetConceptTable.addColumn("CODE").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermConcept.MAX_CODE_LENGTH);
|
||||||
termValueSetCodeTable
|
termValueSetConceptTable
|
||||||
.addIndex("IDX_VALUESET_CODE_CS_CD")
|
.addIndex("IDX_VALUESET_CONCEPT_CS_CD")
|
||||||
.unique(false)
|
.unique(false)
|
||||||
.withColumns("SYSTEM", "CODE");
|
.withColumns("SYSTEM", "CODE");
|
||||||
termValueSetCodeTable.addColumn("DISPLAY").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermConcept.MAX_DESC_LENGTH);
|
termValueSetConceptTable.addColumn("DISPLAY").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermConcept.MAX_DESC_LENGTH);
|
||||||
|
|
||||||
|
// TermValueSetConceptDesignation
|
||||||
|
version.startSectionWithMessage("Processing table: TRM_VALUESET_C_DESIGNATION");
|
||||||
|
version.addIdGenerator("SEQ_VALUESET_C_DSGNTN_PID");
|
||||||
|
Builder.BuilderAddTableByColumns termValueSetConceptDesignationTable = version.addTableByColumns("TRM_VALUESET_C_DESIGNATION", "PID");
|
||||||
|
termValueSetConceptDesignationTable.addColumn("PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
|
||||||
|
termValueSetConceptDesignationTable.addColumn("VALUESET_CONCEPT_PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
|
||||||
|
termValueSetConceptDesignationTable
|
||||||
|
.addForeignKey("FK_TRM_VALUESET_CONCEPT_PID")
|
||||||
|
.toColumn("VALUESET_CONCEPT_PID")
|
||||||
|
.references("TRM_VALUESET_CONCEPT", "PID");
|
||||||
|
termValueSetConceptDesignationTable.addColumn("LANG").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSetConceptDesignation.MAX_LENGTH);
|
||||||
|
termValueSetConceptDesignationTable.addColumn("USE_SYSTEM").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSetConceptDesignation.MAX_LENGTH);
|
||||||
|
termValueSetConceptDesignationTable.addColumn("USE_CODE").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSetConceptDesignation.MAX_LENGTH);
|
||||||
|
termValueSetConceptDesignationTable.addColumn("USE_DISPLAY").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSetConceptDesignation.MAX_LENGTH);
|
||||||
|
termValueSetConceptDesignationTable.addColumn("VAL").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSetConceptDesignation.MAX_LENGTH);
|
||||||
|
termValueSetConceptDesignationTable
|
||||||
|
.addIndex("IDX_VALUESET_C_DSGNTN_VAL")
|
||||||
|
.unique(false)
|
||||||
|
.withColumns("VAL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,13 @@
|
||||||
profiles via the $snapshot operation, and will automatically generate a snapshot when
|
profiles via the $snapshot operation, and will automatically generate a snapshot when
|
||||||
needed for validation.
|
needed for validation.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
Creating/updating CodeSystems now persist <![CDATA[<code>CodeSystem.concept.designation</code>]]> to
|
||||||
|
the terminology tables.
|
||||||
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
Expanded ValueSets now populate <![CDATA[<code>ValueSet.expansion.contains.designation.language</code>]]>.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.8.0" date="2019-05-30" description="Hippo">
|
<release version="3.8.0" date="2019-05-30" description="Hippo">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue