Merge branch 'loinc_loader_update' of github.com:jamesagnew/hapi-fhir into loinc_loader_update

This commit is contained in:
jamesagnew 2018-04-02 22:13:29 -04:00
commit f56151d5a9
36 changed files with 927 additions and 148 deletions

View File

@ -8,9 +8,10 @@ import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.TerminologyUploaderProviderDstu3;
import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.provider.r4.TerminologyUploaderProviderR4;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
@ -78,10 +79,10 @@ public class JpaServerDemo extends RestfulServer {
systemProvider.add(myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class));
} else if (fhirVersion == FhirVersionEnum.DSTU3) {
systemProvider.add(myAppCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProviderDstu3.class));
} else if (fhirVersion == FhirVersionEnum.R4) {
systemProvider.add(myAppCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProviderR4.class));
} else {
throw new IllegalStateException();
}

View File

@ -0,0 +1,28 @@
package ca.uhn.fhir.jpa.dao.data;
import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
import org.springframework.data.jpa.repository.JpaRepository;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public interface ITermConceptDesignationDao extends JpaRepository<TermConceptDesignation, Long> {
// nothing
}

View File

@ -81,6 +81,9 @@ public class TermConcept implements Serializable {
@FieldBridge(impl = TermConceptPropertyFieldBridge.class)
private Collection<TermConceptProperty> myProperties;
@OneToMany(mappedBy = "myConcept", orphanRemoval = true)
private Collection<TermConceptDesignation> myDesignations;
@Id()
@SequenceGenerator(name = "SEQ_CONCEPT_PID", sequenceName = "SEQ_CONCEPT_PID")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_PID")
@ -123,6 +126,13 @@ public class TermConcept implements Serializable {
}
}
public TermConceptDesignation addDesignation() {
TermConceptDesignation designation = new TermConceptDesignation();
designation.setConcept(this);
getDesignations().add(designation);
return designation;
}
private TermConceptProperty addProperty(@Nonnull TermConceptPropertyTypeEnum thePropertyType, @Nonnull String thePropertyName, @Nonnull String thePropertyValue) {
Validate.notBlank(thePropertyName);
@ -189,6 +199,29 @@ public class TermConcept implements Serializable {
}
}
public List<Coding> getCodingProperties(String thePropertyName) {
List<Coding> retVal = new ArrayList<>();
for (TermConceptProperty next : getProperties()) {
if (thePropertyName.equals(next.getKey())) {
if (next.getType() == TermConceptPropertyTypeEnum.CODING) {
Coding coding = new Coding();
coding.setSystem(next.getCodeSystem());
coding.setCode(next.getValue());
coding.setDisplay(next.getDisplay());
retVal.add(coding);
}
}
}
return retVal;
}
public Collection<TermConceptDesignation> getDesignations() {
if (myDesignations == null) {
myDesignations = new ArrayList<>();
}
return myDesignations;
}
public String getDisplay() {
return myDisplay;
}
@ -231,6 +264,14 @@ public class TermConcept implements Serializable {
return myProperties;
}
public Integer getSequence() {
return mySequence;
}
public void setSequence(Integer theSequence) {
mySequence = theSequence;
}
public List<String> getStringProperties(String thePropertyName) {
List<String> retVal = new ArrayList<>();
for (TermConceptProperty next : getProperties()) {
@ -243,30 +284,6 @@ public class TermConcept implements Serializable {
return retVal;
}
public List<Coding> getCodingProperties(String thePropertyName) {
List<Coding> retVal = new ArrayList<>();
for (TermConceptProperty next : getProperties()) {
if (thePropertyName.equals(next.getKey())) {
if (next.getType() == TermConceptPropertyTypeEnum.CODING) {
Coding coding = new Coding();
coding.setSystem(next.getCodeSystem());
coding.setCode(next.getValue());
coding.setDisplay(next.getDisplay());
retVal.add(coding);
}
}
}
return retVal;
}
public Integer getSequence() {
return mySequence;
}
public void setSequence(Integer theSequence) {
mySequence = theSequence;
}
public String getStringProperty(String thePropertyName) {
List<String> properties = getStringProperties(thePropertyName);
if (properties.size() > 0) {

View File

@ -0,0 +1,103 @@
package ca.uhn.fhir.jpa.entity;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "TRM_CONCEPT_DESIG", uniqueConstraints = {
}, indexes = {
})
public class TermConceptDesignation implements Serializable {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "CONCEPT_PID", referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_CONCEPTDESIG_CONCEPT"))
private TermConcept myConcept;
@Id()
@SequenceGenerator(name = "SEQ_CONCEPT_DESIG_PID", sequenceName = "SEQ_CONCEPT_DESIG_PID")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_DESIG_PID")
@Column(name = "PID")
private Long myId;
@Column(name = "LANG", length = 50, nullable = true)
private String myLanguage;
@Column(name = "USE_SYSTEM", length = 50, nullable = true)
private String myUseSystem;
@Column(name = "USE_CODE", length = 50, nullable = true)
private String myUseCode;
@Column(name = "USE_DISPLAY", length = 50, nullable = true)
private String myUseDisplay;
@Column(name = "VAL", length = 50, nullable = false)
private String myValue;
public String getLanguage() {
return myLanguage;
}
public TermConceptDesignation setLanguage(String theLanguage) {
myLanguage = theLanguage;
return this;
}
public String getUseCode() {
return myUseCode;
}
public TermConceptDesignation setUseCode(String theUseCode) {
myUseCode = theUseCode;
return this;
}
public String getUseDisplay() {
return myUseDisplay;
}
public TermConceptDesignation setUseDisplay(String theUseDisplay) {
myUseDisplay = theUseDisplay;
return this;
}
public String getUseSystem() {
return myUseSystem;
}
public TermConceptDesignation setUseSystem(String theUseSystem) {
myUseSystem = theUseSystem;
return this;
}
public String getValue() {
return myValue;
}
public TermConceptDesignation setValue(String theValue) {
myValue = theValue;
return this;
}
public TermConceptDesignation setConcept(TermConcept theConcept) {
myConcept = theConcept;
return this;
}
}

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.entity;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.apache.lucene.document.Document;
import org.hibernate.search.bridge.FieldBridge;
import org.hibernate.search.bridge.LuceneOptions;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.entity;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
/**
* @see TermConceptProperty#getType()
* @see TermConceptProperty#MAX_PROPTYPE_ENUM_LENGTH

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.provider.dstu3;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.provider.BaseTerminologyUploaderProvider;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.provider.r4;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.provider.BaseTerminologyUploaderProvider;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;

View File

@ -78,6 +78,8 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
@Autowired
protected ITermConceptPropertyDao myConceptPropertyDao;
@Autowired
protected ITermConceptDesignationDao myConceptDesignationDao;
@Autowired
protected FhirContext myContext;
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager;
@ -103,6 +105,28 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
contains.setCode(theConcept.getCode());
contains.setSystem(theCodeSystem);
contains.setDisplay(theConcept.getDisplay());
for (TermConceptDesignation nextDesignation : theConcept.getDesignations()) {
contains
.addDesignation()
.setValue(nextDesignation.getValue())
.getUse()
.setSystem(nextDesignation.getUseSystem())
.setCode(nextDesignation.getUseCode())
.setDisplay(nextDesignation.getUseDisplay());
}
}
}
private void addConceptsToList(ValueSet.ValueSetExpansionComponent theExpansionComponent, Set<String> theAddedCodes, String theSystem, List<CodeSystem.ConceptDefinitionComponent> theConcept) {
for (CodeSystem.ConceptDefinitionComponent next : theConcept) {
if (!theAddedCodes.contains(next.getCode())) {
theAddedCodes.add(next.getCode());
ValueSet.ValueSetExpansionContainsComponent contains = theExpansionComponent.addContains();
contains.setCode(next.getCode());
contains.setSystem(theSystem);
contains.setDisplay(next.getDisplay());
}
addConceptsToList(theExpansionComponent, theAddedCodes, theSystem, next.getConcept());
}
}
@ -162,10 +186,12 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
myCodeSystemDao.save(cs);
myCodeSystemDao.flush();
int i = 0;
for (TermCodeSystemVersion next : myCodeSystemVersionDao.findByCodeSystemResource(theCodeSystem.getPid())) {
myConceptParentChildLinkDao.deleteByCodeSystemVersion(next.getPid());
for (TermConcept nextConcept : myConceptDao.findByCodeSystemVersion(next.getPid())) {
myConceptPropertyDao.delete(nextConcept.getProperties());
myConceptDesignationDao.delete(nextConcept.getDesignations());
myConceptDao.delete(nextConcept);
}
if (next.getCodeSystem().getCurrentVersion() == next) {
@ -173,10 +199,15 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
myCodeSystemDao.save(next.getCodeSystem());
}
myCodeSystemVersionDao.delete(next);
if (i % 1000 == 0) {
myEntityManager.flush();
}
}
myCodeSystemVersionDao.deleteForCodeSystem(theCodeSystem);
myCodeSystemDao.delete(theCodeSystem);
myEntityManager.flush();
}
private int ensureParentsSaved(Collection<TermConceptParentChildLink> theParents) {
@ -223,11 +254,13 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
haveIncludeCriteria = true;
TermConcept code = findCode(system, nextCode);
if (code != null) {
addedCodes.add(nextCode);
ValueSet.ValueSetExpansionContainsComponent contains = expansionComponent.addContains();
contains.setCode(nextCode);
contains.setSystem(system);
contains.setDisplay(code.getDisplay());
addCodeIfNotAlreadyAdded(system, expansionComponent, addedCodes, code);
//
// addedCodes.add(nextCode);
// ValueSet.ValueSetExpansionContainsComponent contains = expansionComponent.addContains();
// contains.setCode(nextCode);
// contains.setSystem(system);
// contains.setDisplay(code.getDisplay());
}
}
}
@ -511,6 +544,10 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
myConceptPropertyDao.save(next);
}
for (TermConceptDesignation next : theConcept.getDesignations()) {
myConceptDesignationDao.save(next);
}
}
private void populateVersion(TermConcept theNext, TermCodeSystemVersion theCodeSystemVersion) {

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import org.apache.commons.csv.CSVRecord;
public interface IRecordHandler {

View File

@ -1,8 +1,29 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IRecordHandler;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ContactPoint;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.ValueSet;
@ -65,7 +86,7 @@ abstract class BaseHandler implements IRecordHandler {
}
void addConceptMapEntry(ConceptMapping theMapping) {
void addConceptMapEntry(ConceptMapping theMapping, String theCopyright) {
if (isBlank(theMapping.getSourceCode())) {
return;
}
@ -79,6 +100,13 @@ abstract class BaseHandler implements IRecordHandler {
conceptMap.setId(theMapping.getConceptMapId());
conceptMap.setUrl(theMapping.getConceptMapUri());
conceptMap.setName(theMapping.getConceptMapName());
conceptMap.setPublisher("Regentrief Institute, Inc.");
conceptMap.addContact()
.setName("Regentrief Institute, Inc.")
.addTelecom()
.setSystem(ContactPoint.ContactPointSystem.URL)
.setValue("https://loinc.org");
conceptMap.setCopyright(theCopyright);
myIdToConceptMaps.put(theMapping.getConceptMapId(), conceptMap);
myConceptMaps.add(conceptMap);
} else {
@ -144,6 +172,13 @@ abstract class BaseHandler implements IRecordHandler {
vs.setId(theValueSetId);
vs.setName(theValueSetName);
vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
vs.setPublisher("Regenstrief Institute, Inc.");
vs.addContact()
.setName("Regenstrief Institute, Inc.")
.addTelecom()
.setSystem(ContactPoint.ContactPointSystem.URL)
.setValue("https://loinc.org");
vs.setCopyright("This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/");
myIdToValueSet.put(theValueSetId, vs);
myValueSets.add(vs);
} else {

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
import ca.uhn.fhir.jpa.term.IRecordHandler;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
@ -15,8 +35,8 @@ import static org.apache.commons.lang3.StringUtils.trim;
public class LoincDocumentOntologyHandler extends BaseHandler implements IRecordHandler {
public static final String DOCUMENT_ONTOLOGY_CODES_VS_ID = "DOCUMENT-ONTOLOGY-CODES-VS";
public static final String DOCUMENT_ONTOLOGY_CODES_VS_URI = "http://loinc.org/document-ontology-codes";
public static final String DOCUMENT_ONTOLOGY_CODES_VS_ID = "loinc-document-ontology";
public static final String DOCUMENT_ONTOLOGY_CODES_VS_URI = "http://loinc.org/vs/loinc-document-ontology";
public static final String DOCUMENT_ONTOLOGY_CODES_VS_NAME = "LOINC Document Ontology Codes";
private final Map<String, TermConcept> myCode2Concept;
private final TermCodeSystemVersion myCodeSystemVersion;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IRecordHandler;
@ -37,6 +57,13 @@ public class LoincHandler implements IRecordHandler {
TermConcept concept = new TermConcept(myCodeSystemVersion, code);
concept.setDisplay(display);
if (!display.equalsIgnoreCase(shortName)) {
concept
.addDesignation()
.setUseDisplay("ShortName")
.setValue(shortName);
}
for (String nextPropertyName : myPropertyNames) {
if (!theRecord.toMap().containsKey(nextPropertyName)) {
continue;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
import ca.uhn.fhir.jpa.term.IRecordHandler;
@ -18,6 +38,7 @@ public class LoincIeeeMedicalDeviceCodeHandler extends BaseHandler implements IR
public static final String LOINC_IEEE_CM_ID = "LOINC-IEEE-MEDICAL-DEVICE-CM";
public static final String LOINC_IEEE_CM_URI = "http://loinc.org/fhir/loinc-ieee-device-code-mappings";
public static final String LOINC_IEEE_CM_NAME = "LOINC/IEEE Device Code Mappings";
private static final String CM_COPYRIGHT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC/IEEE Medical Device Code Mapping Table contains content from IEEE (http://ieee.org), copyright © 2017 IEEE.";
/**
* Constructor
@ -48,7 +69,8 @@ public class LoincIeeeMedicalDeviceCodeHandler extends BaseHandler implements IR
.setTargetCodeSystem(targetCodeSystemUri)
.setTargetCode(ieeeCode)
.setTargetDisplay(ieeeDisplayName)
.setEquivalence(Enumerations.ConceptMapEquivalence.EQUAL));
.setEquivalence(Enumerations.ConceptMapEquivalence.EQUAL),
CM_COPYRIGHT);
}

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
import ca.uhn.fhir.jpa.term.IRecordHandler;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IRecordHandler;
@ -9,6 +29,7 @@ import org.hl7.fhir.r4.model.ValueSet;
import java.util.HashMap;
import java.util.Map;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
public class LoincPartHandler implements IRecordHandler {
@ -30,15 +51,23 @@ public class LoincPartHandler implements IRecordHandler {
String partTypeName = trim(theRecord.get("PartTypeName"));
String partName = trim(theRecord.get("PartName"));
String partDisplayName = trim(theRecord.get("PartDisplayName"));
String status = trim(theRecord.get("Status"));
if (!"ACTIVE".equals(status)) {
return;
}
// Per Dan's note, we include deprecated parts
// String status = trim(theRecord.get("Status"));
// if (!"ACTIVE".equals(status)) {
// return;
// }
TermConcept concept = new TermConcept(myCodeSystemVersion, partNumber);
concept.setDisplay(partName);
if (isNotBlank(partDisplayName)) {
concept.addDesignation()
.setConcept(concept)
.setUseDisplay("PartDisplayName")
.setValue(partDisplayName);
}
myCode2Concept.put(partDisplayName, concept);
}

View File

@ -1,20 +1,39 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IRecordHandler;
import org.apache.commons.csv.CSVRecord;
import org.hl7.fhir.r4.model.ValueSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import static org.apache.commons.lang3.StringUtils.trim;
public class LoincPartLinkHandler implements IRecordHandler {
private static final Logger ourLog = LoggerFactory.getLogger(LoincPartLinkHandler.class);
private final Map<String, TermConcept> myCode2Concept;
private final TermCodeSystemVersion myCodeSystemVersion;
@ -33,11 +52,11 @@ public class LoincPartLinkHandler implements IRecordHandler {
TermConcept loincConcept = myCode2Concept.get(loincNumber);
TermConcept partConcept = myCode2Concept.get(partNumber);
if (loincConcept==null) {
if (loincConcept == null) {
ourLog.warn("No loinc code: {}", loincNumber);
return;
}
if (partConcept==null) {
if (partConcept == null) {
ourLog.warn("No part code: {}", partNumber);
return;
}
@ -45,5 +64,4 @@ public class LoincPartLinkHandler implements IRecordHandler {
// For now we're ignoring these
}
private static final Logger ourLog = LoggerFactory.getLogger(LoincPartLinkHandler.class);
}

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
@ -18,8 +38,9 @@ import static org.apache.commons.lang3.StringUtils.trim;
public class LoincPartRelatedCodeMappingHandler extends BaseHandler implements IRecordHandler {
public static final String LOINC_PART_MAP_ID = "LOINC-PART-MAP";
public static final String LOINC_PART_MAP_URI = "http://loinc.org/fhir/loinc-part-map";
public static final String LOINC_PART_MAP_URI = "http://loinc.org/cm/loinc-parts-to-snomed-ct";
public static final String LOINC_PART_MAP_NAME = "LOINC Part Map";
private static final String CM_COPYRIGHT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC Part File, LOINC/SNOMED CT Expression Association and Map Sets File, RELMA database and associated search index files include SNOMED Clinical Terms (SNOMED CT®) which is used by permission of the International Health Terminology Standards Development Organisation (IHTSDO) under license. All rights are reserved. SNOMED CT® was originally created by The College of American Pathologists. “SNOMED” and “SNOMED CT” are registered trademarks of the IHTSDO. Use of SNOMED CT content is subject to the terms and conditions set forth in the SNOMED CT Affiliate License Agreement. It is the responsibility of those implementing this product to ensure they are appropriately licensed and for more information on the license, including how to register as an Affiliate Licensee, please refer to http://www.snomed.org/snomed-ct/get-snomed-ct or info@snomed.org. Under the terms of the Affiliate License, use of SNOMED CT in countries that are not IHTSDO Members is subject to reporting and fee payment obligations. However, IHTSDO agrees to waive the requirements to report and pay fees for use of SNOMED CT content included in the LOINC Part Mapping and LOINC Term Associations for purposes that support or enable more effective use of LOINC. This material includes content from the US Edition to SNOMED CT, which is developed and maintained by the U.S. National Library of Medicine and is available to authorized UMLS Metathesaurus Licensees from the UTS Downloads site at https://uts.nlm.nih.gov.";
private final Map<String, TermConcept> myCode2Concept;
private final TermCodeSystemVersion myCodeSystemVersion;
private final List<ConceptMap> myConceptMaps;
@ -76,7 +97,9 @@ public class LoincPartRelatedCodeMappingHandler extends BaseHandler implements I
.setTargetDisplay(extCodeDisplayName)
.setTargetCodeSystemVersion(extCodeSystemVersion)
.setEquivalence(equivalence)
.setCopyright(extCodeSystemCopyrightNotice));
.setCopyright(extCodeSystemCopyrightNotice),
CM_COPYRIGHT
);
}

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
@ -17,17 +37,27 @@ import static org.apache.commons.lang3.StringUtils.trim;
public class LoincRsnaPlaybookHandler extends BaseHandler implements IRecordHandler {
public static final String RSNA_CODES_VS_ID = "RSNA-LOINC-CODES-VS";
public static final String RSNA_CODES_VS_URI = "http://loinc.org/rsna-codes";
public static final String RSNA_CODES_VS_NAME = "RSNA Playbook";
public static final String RSNA_CODES_VS_ID = "loinc-rsna-radiology-playbook";
public static final String RSNA_CODES_VS_URI = "http://loinc.org/vs/loinc-rsna-radiology-playbook";
public static final String RSNA_CODES_VS_NAME = "LOINC/RSNA Radiology Playbook";
public static final String RID_MAPPING_CM_ID = "LOINC-TO-RID-CODES-CM";
public static final String RID_MAPPING_CM_URI = "http://loinc.org/rid-codes";
public static final String RID_MAPPING_CM_NAME = "RSNA Playbook RID Codes Mapping";
public static final String RID_CS_URI = "http://rid";
public static final String RID_CS_URI = "http://www.radlex.org";
public static final String RPID_MAPPING_CM_ID = "LOINC-TO-RPID-CODES-CM";
public static final String RPID_MAPPING_CM_URI = "http://loinc.org/rpid-codes";
public static final String RPID_MAPPING_CM_NAME = "RSNA Playbook RPID Codes Mapping";
public static final String RPID_CS_URI = "http://rpid";
/*
* About these being the same - Per Dan:
* We had some discussion about this, and both
* RIDs (RadLex clinical terms) and RPIDs (Radlex Playbook Ids)
* belong to the same "code system" since they will never collide.
* The codesystem uri is "http://www.radlex.org". FYI, that's
* now listed on the FHIR page:
* https://www.hl7.org/fhir/terminologies-systems.html
*/
public static final String RPID_CS_URI = RID_CS_URI;
private static final String CM_COPYRIGHT = "This content from LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at https://loinc.org/license/. The LOINC/RSNA Radiology Playbook and the LOINC Part File contain content from RadLex® (http://rsna.org/RadLex.aspx), copyright © 2005-2017, The Radiological Society of North America, Inc., available at no cost under the license at http://www.rsna.org/uploadedFiles/RSNA/Content/Informatics/RadLex_License_Agreement_and_Terms_of_Use_V2_Final.pdf.";
private final Map<String, TermConcept> myCode2Concept;
private final TermCodeSystemVersion myCodeSystemVersion;
private final Set<String> myPropertyNames;
@ -118,7 +148,8 @@ public class LoincRsnaPlaybookHandler extends BaseHandler implements IRecordHand
.setTargetCodeSystem(RID_CS_URI)
.setTargetCode(rid)
.setTargetDisplay(preferredName)
.setEquivalence(Enumerations.ConceptMapEquivalence.EQUAL));
.setEquivalence(Enumerations.ConceptMapEquivalence.EQUAL),
CM_COPYRIGHT);
}
// LOINC Term -> Radlex RPID code mappings
@ -134,7 +165,8 @@ public class LoincRsnaPlaybookHandler extends BaseHandler implements IRecordHand
.setTargetCodeSystem(RPID_CS_URI)
.setTargetCode(rpid)
.setTargetDisplay(longName)
.setEquivalence(Enumerations.ConceptMapEquivalence.EQUAL));
.setEquivalence(Enumerations.ConceptMapEquivalence.EQUAL),
CM_COPYRIGHT);
}
}

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermConcept;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ValueSet;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermConcept;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ValueSet;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.loinc;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
import ca.uhn.fhir.jpa.term.IRecordHandler;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.snomedct;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.term.IRecordHandler;
import org.apache.commons.csv.CSVRecord;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.snomedct;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.term.IRecordHandler;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.term.snomedct;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;

View File

@ -281,6 +281,7 @@ public abstract class BaseJpaTest {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + TermConceptProperty.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermConceptDesignation.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermConcept.class.getSimpleName() + " d").executeUpdate();
for (TermCodeSystem next : entityManager.createQuery("SELECT c FROM " + TermCodeSystem.class.getName() + " c", TermCodeSystem.class).getResultList()) {
next.setCurrentVersion(null);

View File

@ -271,5 +271,10 @@ public class ResourceProviderDstu3CodeSystemTest extends BaseResourceProviderDst
TestUtil.clearAllStaticFieldsForUnitTest();
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -134,7 +134,7 @@ public class TerminologyUploaderProviderDstu3Test extends BaseResourceProviderDs
@Test
public void testUploadMissingUrl() throws Exception {
byte[] packageBytes = createSctZip();
try {
ourClient
.operation()
@ -207,7 +207,7 @@ public class TerminologyUploaderProviderDstu3Test extends BaseResourceProviderDs
assertThat(((IntegerType)respParam.getParameter().get(0).getValue()).getValue(), greaterThan(1));
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();

View File

@ -56,6 +56,11 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
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, RelationshipTypeEnum.ISA);
TermConcept childAB = new TermConcept(cs, "childAB");
@ -193,6 +198,31 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
assertThat(codes, containsInAnyOrder("ParentA", "childAAA", "childAAB", "childAA", "childAB", "ParentB"));
}
@Test
public void testPropertiesAndDesignationsPreservedInExpansion() {
createCodeSystem();
List<String> codes;
ValueSet vs = new ValueSet();
ValueSet.ConceptSetComponent include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.addConcept().setCode("childAAB");
ValueSet outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("childAAB"));
ValueSet.ValueSetExpansionContainsComponent concept = outcome.getExpansion().getContains().get(0);
assertEquals("childAAB", concept.getCode());
assertEquals("http://example.com/my_code_system", concept.getSystem());
assertEquals(null, concept.getDisplay());
assertEquals("D1S", concept.getDesignation().get(0).getUse().getSystem());
assertEquals("D1C", concept.getDesignation().get(0).getUse().getCode());
assertEquals("D1D", concept.getDesignation().get(0).getUse().getDisplay());
assertEquals("D1V", concept.getDesignation().get(0).getValue());
}
@Test
public void testFindCodesAbove() {
IIdType id = createCodeSystem();

View File

@ -8,9 +8,10 @@ import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.TerminologyUploaderProviderDstu3;
import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.provider.r4.TerminologyUploaderProviderR4;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.api.EncodingEnum;
@ -50,6 +51,13 @@ public class TestRestfulServer extends RestfulServer {
private AnnotationConfigWebApplicationContext myAppCtx;
@Override
public void destroy() {
super.destroy();
ourLog.info("Server is shutting down");
myAppCtx.destroy();
}
@SuppressWarnings("unchecked")
@Override
protected void initialize() throws ServletException {
@ -74,79 +82,79 @@ public class TestRestfulServer extends RestfulServer {
ETagSupportEnum etagSupport;
String baseUrlProperty;
List<Object> plainProviders = new ArrayList<Object>();
switch (fhirVersionParam.trim().toUpperCase()) {
case "TDL2":
case "DSTU2": {
myAppCtx = new AnnotationConfigWebApplicationContext();
myAppCtx.setServletConfig(getServletConfig());
myAppCtx.setParent(parentAppCtx);
if ("TDL2".equals(fhirVersionParam.trim().toUpperCase())) {
myAppCtx.register(TdlDstu2Config.class);
baseUrlProperty = FHIR_BASEURL_TDL2;
} else {
myAppCtx.register(TestDstu2Config.class, WebsocketDispatcherConfig.class);
baseUrlProperty = FHIR_BASEURL_DSTU2;
case "TDL2":
case "DSTU2": {
myAppCtx = new AnnotationConfigWebApplicationContext();
myAppCtx.setServletConfig(getServletConfig());
myAppCtx.setParent(parentAppCtx);
if ("TDL2".equals(fhirVersionParam.trim().toUpperCase())) {
myAppCtx.register(TdlDstu2Config.class);
baseUrlProperty = FHIR_BASEURL_TDL2;
} else {
myAppCtx.register(TestDstu2Config.class, WebsocketDispatcherConfig.class);
baseUrlProperty = FHIR_BASEURL_DSTU2;
}
myAppCtx.refresh();
setFhirContext(FhirContext.forDstu2());
beans = myAppCtx.getBean("myResourceProvidersDstu2", List.class);
plainProviders.add(myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class));
systemDao = myAppCtx.getBean("mySystemDaoDstu2", IFhirSystemDao.class);
etagSupport = ETagSupportEnum.ENABLED;
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, systemDao, myAppCtx.getBean(DaoConfig.class));
confProvider.setImplementationDescription(implDesc);
setServerConformanceProvider(confProvider);
break;
}
myAppCtx.refresh();
setFhirContext(FhirContext.forDstu2());
beans = myAppCtx.getBean("myResourceProvidersDstu2", List.class);
plainProviders.add(myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class));
systemDao = myAppCtx.getBean("mySystemDaoDstu2", IFhirSystemDao.class);
etagSupport = ETagSupportEnum.ENABLED;
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(this, systemDao, myAppCtx.getBean(DaoConfig.class));
confProvider.setImplementationDescription(implDesc);
setServerConformanceProvider(confProvider);
break;
}
case "TDL3":
case "DSTU3": {
myAppCtx = new AnnotationConfigWebApplicationContext();
myAppCtx.setServletConfig(getServletConfig());
myAppCtx.setParent(parentAppCtx);
if ("TDL3".equals(fhirVersionParam.trim().toUpperCase())) {
myAppCtx.register(TdlDstu3Config.class);
baseUrlProperty = FHIR_BASEURL_TDL3;
} else {
myAppCtx.register(TestDstu3Config.class, WebsocketDispatcherConfig.class);
baseUrlProperty = FHIR_BASEURL_DSTU3;
case "TDL3":
case "DSTU3": {
myAppCtx = new AnnotationConfigWebApplicationContext();
myAppCtx.setServletConfig(getServletConfig());
myAppCtx.setParent(parentAppCtx);
if ("TDL3".equals(fhirVersionParam.trim().toUpperCase())) {
myAppCtx.register(TdlDstu3Config.class);
baseUrlProperty = FHIR_BASEURL_TDL3;
} else {
myAppCtx.register(TestDstu3Config.class, WebsocketDispatcherConfig.class);
baseUrlProperty = FHIR_BASEURL_DSTU3;
}
myAppCtx.refresh();
setFhirContext(FhirContext.forDstu3());
beans = myAppCtx.getBean("myResourceProvidersDstu3", List.class);
plainProviders.add(myAppCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class));
systemDao = myAppCtx.getBean("mySystemDaoDstu3", IFhirSystemDao.class);
etagSupport = ETagSupportEnum.ENABLED;
JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(this, systemDao, myAppCtx.getBean(DaoConfig.class));
confProvider.setImplementationDescription(implDesc);
setServerConformanceProvider(confProvider);
plainProviders.add(myAppCtx.getBean(TerminologyUploaderProviderDstu3.class));
break;
}
myAppCtx.refresh();
setFhirContext(FhirContext.forDstu3());
beans = myAppCtx.getBean("myResourceProvidersDstu3", List.class);
plainProviders.add(myAppCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class));
systemDao = myAppCtx.getBean("mySystemDaoDstu3", IFhirSystemDao.class);
etagSupport = ETagSupportEnum.ENABLED;
JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(this, systemDao, myAppCtx.getBean(DaoConfig.class));
confProvider.setImplementationDescription(implDesc);
setServerConformanceProvider(confProvider);
plainProviders.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
break;
case "R4": {
myAppCtx = new AnnotationConfigWebApplicationContext();
myAppCtx.setServletConfig(getServletConfig());
myAppCtx.setParent(parentAppCtx);
myAppCtx.register(TestR4Config.class, WebsocketDispatcherConfig.class);
baseUrlProperty = FHIR_BASEURL_R4;
myAppCtx.refresh();
setFhirContext(FhirContext.forR4());
beans = myAppCtx.getBean("myResourceProvidersR4", List.class);
plainProviders.add(myAppCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class));
systemDao = myAppCtx.getBean("mySystemDaoR4", IFhirSystemDao.class);
etagSupport = ETagSupportEnum.ENABLED;
JpaConformanceProviderR4 confProvider = new JpaConformanceProviderR4(this, systemDao, myAppCtx.getBean(DaoConfig.class));
confProvider.setImplementationDescription(implDesc);
setServerConformanceProvider(confProvider);
plainProviders.add(myAppCtx.getBean(TerminologyUploaderProviderR4.class));
break;
}
default:
throw new ServletException("Unknown FHIR version specified in init-param[FhirVersion]: " + fhirVersionParam);
}
case "R4": {
myAppCtx = new AnnotationConfigWebApplicationContext();
myAppCtx.setServletConfig(getServletConfig());
myAppCtx.setParent(parentAppCtx);
myAppCtx.register(TestR4Config.class, WebsocketDispatcherConfig.class);
baseUrlProperty = FHIR_BASEURL_R4;
myAppCtx.refresh();
setFhirContext(FhirContext.forR4());
beans = myAppCtx.getBean("myResourceProvidersR4", List.class);
plainProviders.add(myAppCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class));
systemDao = myAppCtx.getBean("mySystemDaoR4", IFhirSystemDao.class);
etagSupport = ETagSupportEnum.ENABLED;
JpaConformanceProviderR4 confProvider = new JpaConformanceProviderR4(this, systemDao, myAppCtx.getBean(DaoConfig.class));
confProvider.setImplementationDescription(implDesc);
setServerConformanceProvider(confProvider);
plainProviders.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
break;
}
default:
throw new ServletException("Unknown FHIR version specified in init-param[FhirVersion]: " + fhirVersionParam);
}
/*
* On the DSTU2 endpoint, we want to enable ETag support
* On the DSTU2 endpoint, we want to enable ETag support
*/
setETagSupport(etagSupport);
@ -155,9 +163,9 @@ public class TestRestfulServer extends RestfulServer {
*/
FhirContext ctx = getFhirContext();
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
/*
* The resource and system providers (which actually implement the various FHIR
* The resource and system providers (which actually implement the various FHIR
* operations in this server) are all retrieved from the spring context above
* and are provided to the server here.
*/
@ -187,17 +195,17 @@ public class TestRestfulServer extends RestfulServer {
responseHighlighterInterceptor.setShowRequestHeaders(false);
responseHighlighterInterceptor.setShowResponseHeaders(true);
registerInterceptor(responseHighlighterInterceptor);
registerInterceptor(new BanUnsupportedHttpMethodsInterceptor());
/*
* Default to JSON with pretty printing
*/
setDefaultPrettyPrint(true);
setDefaultResponseEncoding(EncodingEnum.JSON);
/*
* The server's base URL (e.g. http://fhirtest.uhn.ca/baseDstu2) is
* The server's base URL (e.g. http://fhirtest.uhn.ca/baseDstu2) is
* pulled from a system property, which is helpful if you want to try
* hosting your own copy of this server.
*/
@ -210,12 +218,12 @@ public class TestRestfulServer extends RestfulServer {
}
}
setServerAddressStrategy(new MyHardcodedServerAddressStrategy(baseUrl));
/*
* Spool results to the database
* Spool results to the database
*/
setPagingProvider(myAppCtx.getBean(DatabaseBackedPagingProvider.class));
/*
* Load interceptors for the server from Spring
*/
@ -226,13 +234,6 @@ public class TestRestfulServer extends RestfulServer {
}
@Override
public void destroy() {
super.destroy();
ourLog.info("Server is shutting down");
myAppCtx.destroy();
}
/**
* The public server is deployed to http://fhirtest.uhn.ca and the JEE webserver
* where this FHIR server is deployed is actually fronted by an Apache HTTPd instance,
@ -248,7 +249,7 @@ public class TestRestfulServer extends RestfulServer {
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
/*
* This is a bit of a hack, but we want to support both HTTP and HTTPS seamlessly
* so we have the outer httpd proxy relay requests to the Java container on
* so we have the outer httpd proxy relay requests to the Java container on
* port 28080 for http and 28081 for https.
*/
String retVal = super.determineServerBase(theServletContext, theRequest);
@ -257,8 +258,8 @@ public class TestRestfulServer extends RestfulServer {
}
return retVal;
}
}
}

View File

@ -1,7 +1,7 @@
package ca.uhn.fhirtest.interceptor;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProvider;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.provider.BaseTerminologyUploaderProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException;
import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor;
@ -16,8 +16,8 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
public class PublicSecurityInterceptor extends AuthorizationInterceptor {
private HashSet<String> myTokens;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PublicSecurityInterceptor.class);
private HashSet<String> myTokens;
public PublicSecurityInterceptor() {
String passwordsString = System.getProperty("fhir.tdlpass");
@ -34,7 +34,7 @@ public class PublicSecurityInterceptor extends AuthorizationInterceptor {
if (isBlank(authHeader)) {
return new RuleBuilder()
.deny().operation().named(BaseJpaSystemProvider.MARK_ALL_RESOURCES_FOR_REINDEXING).onServer().andThen()
.deny().operation().named(TerminologyUploaderProvider.UPLOAD_EXTERNAL_CODE_SYSTEM).onServer().andThen()
.deny().operation().named(BaseTerminologyUploaderProvider.UPLOAD_EXTERNAL_CODE_SYSTEM).onServer().andThen()
.allowAll()
.build();
}

View File

@ -6,6 +6,36 @@
<title>HAPI FHIR Changelog</title>
</properties>
<body>
<release version="3.4.0" date="TBD">
<action type="fix">
When performing a FHIR resource update in the JPA server
where the update happens within a transaction, and the
resource being updated contains placeholder IDs, and
the resource has not actually changed, a new version was
created even though there was not actually any change.
This particular combination of circumstances seems very
specific and improbable, but it is quite common for some
types of solutions (e.g. mapping HL7v2 data) so this
fix can prevent significant wasted space in some cases.
</action>
<action type="fix">
JPA server index tables did not have a column length specified
on the resource type column. This caused the default of 255 to
be used, which wasted a lot of space since resource names are all
less than 30 chars long and a single resource can have 10-100+
index rows depending on configuration. This has now been set
to a much more sensible 30.
</action>
<action type="fix">
The LOINC uploader for the JPA Terminology Server has been
significantly beefed up so that it now takes in the full
set of LOINC distribution artifacts, and creates not only
the LOINC CodeSystem but a complete set of concept properties,
a number of LOINC ValueSets, and a number of LOINC ConceptMaps.
This work was sponsored by the Regenstrief Institute. Thanks
to Regenstrief for their support!
</action>
</release>
<release version="3.3.0" date="2018-03-29">
<action type="add">
This release corrects an inefficiency in the JPA Server, but requires a schema