Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dataset #48

Merged
merged 1 commit into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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