forked from Luke-Sikina/picsure-search-refinement
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ALS-7336] Show specific ancestors in details
- Lots of weird BDC stuff. We decorate the concept with them
- Loading branch information
Luke Sikina
committed
Sep 20, 2024
1 parent
a26a253
commit 807aba8
Showing
16 changed files
with
364 additions
and
28 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
src/main/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptDecoratorService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package edu.harvard.dbmi.avillach.dictionary.concept; | ||
|
||
import edu.harvard.dbmi.avillach.dictionary.concept.model.Concept; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Lazy; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
import java.util.function.Predicate; | ||
import java.util.stream.Stream; | ||
|
||
@Service | ||
public class ConceptDecoratorService { | ||
|
||
private static final Logger LOG = LoggerFactory.getLogger(ConceptDecoratorService.class); | ||
private final boolean enabled; | ||
private final ConceptService conceptService; | ||
|
||
private static final int COMPLIANT = 4, NON_COMPLIANT_TABLED = 3, NON_COMPLIANT_UNTABLED = 2; | ||
|
||
@Autowired | ||
public ConceptDecoratorService( | ||
@Value("${dashboard.enable.extra_details}") boolean enabled, | ||
@Lazy ConceptService conceptService // circular dep | ||
) { | ||
this.enabled = enabled; | ||
this.conceptService = conceptService; | ||
} | ||
|
||
|
||
public Concept populateParentConcepts(Concept concept) { | ||
if (!enabled) { | ||
return concept; | ||
} | ||
|
||
// In some environments, certain parent concepts have critical details that we need to add to the detailed response | ||
List<String> conceptNodes = Stream.of(concept.conceptPath() | ||
.split("\\\\")).filter(Predicate.not(String::isBlank)).toList(); // you have to double escape the slash. Once for strings, and once for regex | ||
|
||
return switch (conceptNodes.size()) { | ||
case COMPLIANT, NON_COMPLIANT_TABLED -> populateTabledConcept(concept, conceptNodes); | ||
case NON_COMPLIANT_UNTABLED -> populateNonCompliantTabledConcept(concept, conceptNodes); | ||
default -> { | ||
LOG.warn("Ignoring decoration request for weird concept path {}", concept.conceptPath()); | ||
yield concept; | ||
} | ||
}; | ||
} | ||
|
||
private Concept populateTabledConcept(Concept concept, List<String> conceptNodes) { | ||
String studyPath = "\\" + String.join("\\", conceptNodes.subList(0, 1)) + "\\"; | ||
String tablePath = "\\" + String.join("\\", conceptNodes.subList(0, 2)) + "\\"; | ||
Concept study = conceptService.conceptDetailWithoutAncestors(concept.dataset(), studyPath).orElse(null); | ||
Concept table = conceptService.conceptDetailWithoutAncestors(concept.dataset(), tablePath).orElse(null); | ||
return concept.withStudy(study).withTable(table); | ||
} | ||
|
||
private Concept populateNonCompliantTabledConcept(Concept concept, List<String> conceptNodes) { | ||
String studyPath = String.join("\\", conceptNodes.subList(0, 1)); | ||
Concept study = conceptService.conceptDetail(concept.dataset(), studyPath).orElse(null); | ||
return concept.withStudy(study); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptDecoratorServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package edu.harvard.dbmi.avillach.dictionary.concept; | ||
|
||
import edu.harvard.dbmi.avillach.dictionary.concept.model.CategoricalConcept; | ||
import edu.harvard.dbmi.avillach.dictionary.concept.model.Concept; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
|
||
import java.util.Optional; | ||
|
||
|
||
@SpringBootTest | ||
class ConceptDecoratorServiceTest { | ||
|
||
@MockBean | ||
ConceptService conceptService; | ||
|
||
@Autowired | ||
ConceptDecoratorService subject; | ||
|
||
@Test | ||
void shouldPopulateCompliantStudy() { | ||
CategoricalConcept concept = new CategoricalConcept("\\study\\table\\idk\\concept\\", "dataset"); | ||
CategoricalConcept table = new CategoricalConcept("\\study\\table\\", "dataset"); | ||
CategoricalConcept study = new CategoricalConcept("\\study\\", "dataset"); | ||
|
||
Mockito.when(conceptService.conceptDetail("dataset", table.dataset())) | ||
.thenReturn(Optional.of(table)); | ||
Mockito.when(conceptService.conceptDetail("dataset", study.dataset())) | ||
.thenReturn(Optional.of(study)); | ||
|
||
Concept actual = subject.populateParentConcepts(concept); | ||
Concept expected = concept.withStudy(study).withTable(table); | ||
|
||
Assertions.assertEquals(expected, actual); | ||
} | ||
|
||
@Test | ||
void shouldPopulateNonCompliantTabledStudy() { | ||
CategoricalConcept concept = new CategoricalConcept("\\study\\table\\concept\\", "dataset"); | ||
CategoricalConcept table = new CategoricalConcept("\\study\\table\\", "dataset"); | ||
CategoricalConcept study = new CategoricalConcept("\\study\\", "dataset"); | ||
|
||
Mockito.when(conceptService.conceptDetail("dataset", table.dataset())) | ||
.thenReturn(Optional.of(table)); | ||
Mockito.when(conceptService.conceptDetail("dataset", study.dataset())) | ||
.thenReturn(Optional.of(study)); | ||
|
||
Concept actual = subject.populateParentConcepts(concept); | ||
Concept expected = concept.withStudy(study).withTable(table); | ||
|
||
Assertions.assertEquals(expected, actual); | ||
} | ||
|
||
@Test | ||
void shouldPopulateNonCompliantUnTabledStudy() { | ||
CategoricalConcept concept = new CategoricalConcept("\\study\\concept\\", "dataset"); | ||
CategoricalConcept study = new CategoricalConcept("\\study\\", "dataset"); | ||
|
||
Mockito.when(conceptService.conceptDetail("dataset", study.dataset())) | ||
.thenReturn(Optional.of(study)); | ||
|
||
Concept actual = subject.populateParentConcepts(concept); | ||
Concept expected = concept.withStudy(study); | ||
|
||
Assertions.assertEquals(expected, actual); | ||
} | ||
|
||
@Test | ||
void shouldNotPopulateWeirdConcept() { | ||
CategoricalConcept concept = new CategoricalConcept("\\1\\2\\3\\4\\5\\6\\", "dataset"); | ||
Concept actual = subject.populateParentConcepts(concept); | ||
|
||
Assertions.assertEquals(concept, actual); | ||
} | ||
} |
Oops, something went wrong.