|
3 | 3 | import static org.ohdsi.webapi.service.cscompare.ConceptSetCompareService.CONCEPT_SET_COMPARISON_ROW_MAPPER;
|
4 | 4 | import static org.ohdsi.webapi.util.SecurityUtils.whitelist;
|
5 | 5 |
|
| 6 | +import com.fasterxml.jackson.core.JsonProcessingException; |
| 7 | +import com.fasterxml.jackson.databind.ObjectMapper; |
6 | 8 | import com.google.common.collect.Lists;
|
7 | 9 | import com.google.common.collect.Maps;
|
8 | 10 |
|
|
78 | 80 | import org.springframework.jdbc.core.RowCallbackHandler;
|
79 | 81 | import org.springframework.jdbc.core.RowMapper;
|
80 | 82 | import org.springframework.stereotype.Component;
|
| 83 | +import org.ohdsi.webapi.vocabulary.MappedRelatedConcept; |
81 | 84 |
|
82 | 85 | /**
|
83 | 86 | * Provides REST services for working with
|
@@ -138,7 +141,10 @@ public void customize(CacheManager cacheManager) {
|
138 | 141 |
|
139 | 142 | @Autowired
|
140 | 143 | private ConceptSetCompareService conceptSetCompareService;
|
141 |
| - |
| 144 | + |
| 145 | + @Autowired |
| 146 | + private ObjectMapper objectMapper; |
| 147 | + |
142 | 148 | @Value("${datasource.driverClassName}")
|
143 | 149 | private String driver;
|
144 | 150 |
|
@@ -827,7 +833,75 @@ public Collection<RelatedConcept> getRelatedConcepts(@PathParam("sourceKey") Str
|
827 | 833 | return concepts.values();
|
828 | 834 | }
|
829 | 835 |
|
830 |
| - /** |
| 836 | + @POST |
| 837 | + @Path("{sourceKey}/related-standard") |
| 838 | + @Produces(MediaType.APPLICATION_JSON) |
| 839 | + public Collection<MappedRelatedConcept> getRelatedStandardMappedConcepts(@PathParam("sourceKey") String sourceKey, List<Long> allConceptIds) { |
| 840 | + Source source = getSourceRepository().findBySourceKey(sourceKey); |
| 841 | + String relatedConceptsSQLPath = "/resources/vocabulary/sql/getRelatedStandardMappedConcepts.sql"; |
| 842 | + String relatedMappedFromIdsSQLPath = "/resources/vocabulary/sql/getRelatedStandardMappedConcepts_getMappedFromIds.sql"; |
| 843 | + String tableQualifier = source.getTableQualifier(SourceDaimon.DaimonType.Vocabulary); |
| 844 | + |
| 845 | + String[] searchStrings = {"CDM_schema"}; |
| 846 | + String[] replacementStrings = {tableQualifier}; |
| 847 | + |
| 848 | + String[] varNames = {"conceptIdList"}; |
| 849 | + |
| 850 | + final Map<Long, MappedRelatedConcept> resultCombinedMappedConcepts = new HashMap<>(); |
| 851 | + final Map<Long, RelatedConcept> relatedStandardConcepts = new HashMap<>(); |
| 852 | + for(final List<Long> conceptIdsBatch: Lists.partition(allConceptIds, PreparedSqlRender.getParameterLimit(source))) { |
| 853 | + Object[] varValues = {conceptIdsBatch.toArray()}; |
| 854 | + PreparedStatementRenderer relatedConceptsRenderer = new PreparedStatementRenderer(source, relatedConceptsSQLPath, searchStrings, replacementStrings, varNames, varValues); |
| 855 | + getSourceJdbcTemplate(source).query(relatedConceptsRenderer.getSql(), relatedConceptsRenderer.getSetter(), (RowMapper<Void>) (resultSet, arg1) -> { |
| 856 | + addRelationships(relatedStandardConcepts, resultSet); |
| 857 | + return null; |
| 858 | + }); |
| 859 | + |
| 860 | + final Map<Long, Set<Long>> relatedNonStandardConceptIdsByStandardId = new HashMap<>(); |
| 861 | + |
| 862 | + PreparedStatementRenderer mappedFromConceptsRenderer = new PreparedStatementRenderer(source, relatedMappedFromIdsSQLPath, searchStrings, replacementStrings, varNames, varValues); |
| 863 | + getSourceJdbcTemplate(source).query(mappedFromConceptsRenderer.getSql(), mappedFromConceptsRenderer.getSetter(), (RowMapper<Void>) (resultSet, arg1) -> { |
| 864 | + populateRelatedConceptIds(relatedNonStandardConceptIdsByStandardId, resultSet); |
| 865 | + return null; |
| 866 | + }); |
| 867 | + |
| 868 | + enrichResultCombinedMappedConcepts(resultCombinedMappedConcepts, relatedStandardConcepts, relatedNonStandardConceptIdsByStandardId); |
| 869 | + } |
| 870 | + return resultCombinedMappedConcepts.values(); |
| 871 | + } |
| 872 | + |
| 873 | + private void populateRelatedConceptIds(final Map<Long, Set<Long>> mappedConceptsIds, final ResultSet resultSet) throws SQLException { |
| 874 | + final Long concept_id = resultSet.getLong("CONCEPT_ID"); |
| 875 | + if (!mappedConceptsIds.containsKey(concept_id)) { |
| 876 | + Set<Long> mappedIds = new HashSet<>(); |
| 877 | + mappedIds.add(resultSet.getLong("MAPPED_FROM_ID")); |
| 878 | + mappedConceptsIds.put(concept_id,mappedIds); |
| 879 | + } else { |
| 880 | + mappedConceptsIds.get(concept_id).add(resultSet.getLong("MAPPED_FROM_ID")); |
| 881 | + } |
| 882 | + } |
| 883 | + |
| 884 | + void enrichResultCombinedMappedConcepts(Map<Long, MappedRelatedConcept> resultCombinedMappedConcepts, |
| 885 | + Map<Long, RelatedConcept> relatedStandardConcepts, |
| 886 | + Map<Long, Set<Long>> relatedNonStandardConceptIdsByStandardId) { |
| 887 | + relatedNonStandardConceptIdsByStandardId.forEach((standardConceptId, mappedFromIds)->{ |
| 888 | + if(resultCombinedMappedConcepts.containsKey(standardConceptId)){ |
| 889 | + resultCombinedMappedConcepts.get(standardConceptId).mappedFromIds.addAll(mappedFromIds); |
| 890 | + } else { |
| 891 | + MappedRelatedConcept mappedRelatedConcept; |
| 892 | + try { |
| 893 | + mappedRelatedConcept = objectMapper.readValue(objectMapper.writeValueAsString(relatedStandardConcepts.get(standardConceptId)), MappedRelatedConcept.class); |
| 894 | + mappedRelatedConcept.mappedFromIds=mappedFromIds; |
| 895 | + resultCombinedMappedConcepts.put(standardConceptId,mappedRelatedConcept); |
| 896 | + } catch (JsonProcessingException e) { |
| 897 | + log.error("Could not convert RelatedConcept to MappedRelatedConcept", e); |
| 898 | + throw new WebApplicationException(e); |
| 899 | + } |
| 900 | + } |
| 901 | + }); |
| 902 | + } |
| 903 | + |
| 904 | + /** |
831 | 905 | * Get ancestor and descendant concepts for the selected concept identifier
|
832 | 906 | * from a source.
|
833 | 907 | *
|
|
0 commit comments