Skip to content

Commit

Permalink
[ALS-7437] Switch study to dataset for concept node detail
Browse files Browse the repository at this point in the history
  • Loading branch information
Luke Sikina authored and Luke-Sikina committed Oct 11, 2024
1 parent a778ee8 commit e749611
Show file tree
Hide file tree
Showing 18 changed files with 895 additions and 175 deletions.
402 changes: 402 additions & 0 deletions code-formatting/eclipse-formatter.xml

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions code-formatting/pre-commit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/sh -e
CWD=$(pwd)
cd $(git rev-parse --show-toplevel)
format_cmd=""

# skip if NO_VERIFY env var set
if [ "$NO_VERIFY" ]; then
echo 'code formatting skipped' 1>&2
exit 0
fi

# I'm not great at bash, so this is a bit ugly, but I'll explain each pipe
# 1. Get all staged files
# 2. Reduce to just .java files
# 3. Replace newlines with commas (this was really hard to do in sed)
# 4. Replace commas with $,^.*
# 5. Crop off the last 4 chars
# This results in foo.java$,^.*bar.java$,^.*baz.java$
# I then append ^.* to the beginning of that.
STAGED_JAVA_FILES_AS_REGEX=$(git diff --staged --name-only --diff-filter=ACMR | grep '.java$' | tr '\n' ',' | sed -e 's/,/$,^.*/g' | sed 's/.\{4\}$//')
FILES_TO_RESTAGE=$(git diff --staged --name-only --diff-filter=ACMR)
if [ -n "$STAGED_JAVA_FILES_AS_REGEX" ]; then
echo "Found the following staged java files to format: $STAGED_JAVA_FILES_AS_REGEX"
mvn spotless:apply -DspotlessFiles=^.*$STAGED_JAVA_FILES_AS_REGEX
git add $FILES_TO_RESTAGE
fi

cd $CWD
15 changes: 15 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<description>Data Dictionary API</description>
<properties>
<java.version>21</java.version>
<spotless.version>2.41.1</spotless.version>
</properties>
<dependencies>
<dependency>
Expand Down Expand Up @@ -74,6 +75,20 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless.version}</version>
<configuration>
<java>
<eclipse>
<version>4.26</version>
<file>code-formatting/eclipse-formatter.xml</file>
</eclipse>
<toggleOffOn />
</java>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package edu.harvard.dbmi.avillach.dictionary.concept;

import edu.harvard.dbmi.avillach.dictionary.concept.model.Concept;
import edu.harvard.dbmi.avillach.dictionary.dataset.Dataset;
import edu.harvard.dbmi.avillach.dictionary.dataset.DatasetService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -9,6 +11,7 @@
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;

Expand All @@ -18,16 +21,18 @@ public class ConceptDecoratorService {
private static final Logger LOG = LoggerFactory.getLogger(ConceptDecoratorService.class);
private final boolean enabled;
private final ConceptService conceptService;
private final DatasetService datasetService;

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
@Value("${dashboard.enable.extra_details}") boolean enabled, @Lazy ConceptService conceptService, DatasetService datasetService // circular
// dep
) {
this.enabled = enabled;
this.conceptService = conceptService;
this.datasetService = datasetService;
}


Expand All @@ -37,8 +42,20 @@ public Concept populateParentConcepts(Concept 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
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);
Expand All @@ -51,16 +68,14 @@ public Concept populateParentConcepts(Concept 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);
Dataset study = datasetService.getDataset(concept.dataset()).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);
Dataset study = datasetService.getDataset(concept.dataset()).orElse(null);
return concept.withStudy(study);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.harvard.dbmi.avillach.dictionary.concept.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import edu.harvard.dbmi.avillach.dictionary.dataset.Dataset;
import jakarta.annotation.Nullable;

import java.util.List;
Expand All @@ -12,31 +13,27 @@ public record CategoricalConcept(

List<String> values, boolean allowFiltering, String studyAcronym,

@Nullable
List<Concept> children,
@Nullable List<Concept> children,

@Nullable
Map<String, String> meta,
@Nullable Map<String, String> meta,

@Nullable
Concept table,
@Nullable Concept table,

@Nullable
Concept study
@Nullable Dataset study

) implements Concept {

public CategoricalConcept(
String conceptPath, String name, String display, String dataset, String description, List<String> values,
boolean allowFiltering, String studyAcronym, @Nullable List<Concept> children, @Nullable Map<String, String> meta
String conceptPath, String name, String display, String dataset, String description, List<String> values, boolean allowFiltering,
String studyAcronym, @Nullable List<Concept> children, @Nullable Map<String, String> meta
) {
this(conceptPath, name, display, dataset, description, values, allowFiltering, studyAcronym, children, meta, null, null);
}

public CategoricalConcept(CategoricalConcept core, Map<String, String> meta) {
this(
core.conceptPath, core.name, core.display, core.dataset, core.description, core.values,
core.allowFiltering, core.studyAcronym, core.children, meta
core.conceptPath, core.name, core.display, core.dataset, core.description, core.values, core.allowFiltering, core.studyAcronym,
core.children, meta
);
}

Expand Down Expand Up @@ -66,7 +63,7 @@ public Concept withTable(Concept table) {
}

@Override
public Concept withStudy(Concept study) {
public Concept withStudy(Dataset study) {
return new CategoricalConcept(
conceptPath, name, display, dataset, description, values, allowFiltering, studyAcronym, children, meta, table, study
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import edu.harvard.dbmi.avillach.dictionary.dataset.Dataset;
import jakarta.annotation.Nullable;

import java.util.List;
Expand All @@ -16,12 +17,11 @@
// - The name is set in the 'type' property
// - For each possible Concept type, here is what the 'type' property will be
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ContinuousConcept.class, name = "Continuous"),
@JsonSubTypes.Type(value = CategoricalConcept.class, name = "Categorical"),
})
public sealed interface Concept
permits CategoricalConcept, ConceptShell, ContinuousConcept {
@JsonSubTypes(
{@JsonSubTypes.Type(value = ContinuousConcept.class, name = "Continuous"),
@JsonSubTypes.Type(value = CategoricalConcept.class, name = "Categorical"),}
)
public sealed interface Concept permits CategoricalConcept, ConceptShell, ContinuousConcept {

/**
* @return The complete concept path for this concept (// delimited)
Expand Down Expand Up @@ -53,7 +53,7 @@ public sealed interface Concept

Concept table();

Concept study();
Dataset study();

Map<String, String> meta();

Expand All @@ -68,7 +68,7 @@ default boolean allowFiltering() {

Concept withTable(Concept table);

Concept withStudy(Concept study);
Concept withStudy(Dataset study);

default boolean conceptEquals(Object object) {
if (this == object) return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package edu.harvard.dbmi.avillach.dictionary.concept.model;

import edu.harvard.dbmi.avillach.dictionary.dataset.Dataset;
import jakarta.annotation.Nullable;

import java.util.List;
Expand Down Expand Up @@ -33,7 +34,7 @@ public Concept table() {
}

@Override
public Concept study() {
public Dataset study() {
return null;
}

Expand All @@ -58,7 +59,7 @@ public Concept withTable(Concept table) {
}

@Override
public Concept withStudy(Concept study) {
public Concept withStudy(Dataset study) {
return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.harvard.dbmi.avillach.dictionary.concept.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import edu.harvard.dbmi.avillach.dictionary.dataset.Dataset;
import jakarta.annotation.Nullable;

import java.util.ArrayList;
Expand All @@ -11,32 +12,24 @@
public record ContinuousConcept(
String conceptPath, String name, String display, String dataset, String description, boolean allowFiltering,

@Nullable Float min, @Nullable Float max, String studyAcronym,
Map<String, String> meta,
@Nullable
List<Concept> children,
@Nullable Float min, @Nullable Float max, String studyAcronym, Map<String, String> meta, @Nullable List<Concept> children,

@Nullable
Concept table,
@Nullable Concept table,

@Nullable
Concept study
@Nullable Dataset study
) implements Concept {

public ContinuousConcept(
String conceptPath, String name, String display, String dataset, String description, boolean allowFiltering,
@Nullable Float min, @Nullable Float max, String studyAcronym, Map<String, String> meta, @Nullable List<Concept> children
String conceptPath, String name, String display, String dataset, String description, boolean allowFiltering, @Nullable Float min,
@Nullable Float max, String studyAcronym, Map<String, String> meta, @Nullable List<Concept> children
) {
this(
conceptPath, name, display, dataset, description, allowFiltering,
min, max, studyAcronym, meta, children, null, null
);
this(conceptPath, name, display, dataset, description, allowFiltering, min, max, studyAcronym, meta, children, null, null);
}

public ContinuousConcept(ContinuousConcept core, Map<String, String> meta) {
this(
core.conceptPath, core.name, core.display, core.dataset, core.description, core.allowFiltering,
core.min, core.max, core.studyAcronym, meta, core.children
core.conceptPath, core.name, core.display, core.dataset, core.description, core.allowFiltering, core.min, core.max,
core.studyAcronym, meta, core.children
);
}

Expand All @@ -45,8 +38,8 @@ public ContinuousConcept(String conceptPath, String dataset) {
}

public ContinuousConcept(
String conceptPath, String name, String display, String dataset, String description, boolean allowFiltering,
@Nullable Float min, @Nullable Float max, String studyAcronym, Map<String, String> meta
String conceptPath, String name, String display, String dataset, String description, boolean allowFiltering, @Nullable Float min,
@Nullable Float max, String studyAcronym, Map<String, String> meta
) {
this(conceptPath, name, display, dataset, description, allowFiltering, min, max, studyAcronym, meta, null);
}
Expand All @@ -67,16 +60,14 @@ public ContinuousConcept withChildren(List<Concept> children) {
@Override
public Concept withTable(Concept table) {
return new ContinuousConcept(
conceptPath, name, display, dataset, description, allowFiltering,
min, max, studyAcronym, meta, children, table, study
conceptPath, name, display, dataset, description, allowFiltering, min, max, studyAcronym, meta, children, table, study
);
}

@Override
public Concept withStudy(Concept study) {
public Concept withStudy(Dataset study) {
return new ContinuousConcept(
conceptPath, name, display, dataset, description, allowFiltering,
min, max, studyAcronym, meta, children, table, study
conceptPath, name, display, dataset, description, allowFiltering, min, max, studyAcronym, meta, children, table, study
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package edu.harvard.dbmi.avillach.dictionary.dataset;

import jakarta.annotation.Nullable;

import java.util.Map;

public record Dataset(String ref, String fullName, String abbreviation, String description, @Nullable Map<String, String> meta) {

public Dataset(String ref, String fullName, String abbreviation, String description) {
this(ref, fullName, abbreviation, description, null);
}

public Dataset withMeta(Map<String, String> meta) {
return new Dataset(ref, fullName, abbreviation, description, meta);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package edu.harvard.dbmi.avillach.dictionary.dataset;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import java.sql.ResultSet;
import java.sql.SQLException;

@Component
public class DatasetMapper implements RowMapper<Dataset> {
@Override
public Dataset mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Dataset(rs.getString("ref"), rs.getString("full_name"), rs.getString("abbreviation"), rs.getString("description"));
}
}
Loading

0 comments on commit e749611

Please sign in to comment.