Skip to content

Commit

Permalink
Merge pull request #646 from imranmaj/demographics-cleanup2
Browse files Browse the repository at this point in the history
Demographics minor refactor 2
  • Loading branch information
DwayneJengSage authored Feb 9, 2023
2 parents 6256ce8 + 9396b57 commit 8ef64fc
Show file tree
Hide file tree
Showing 44 changed files with 297 additions and 200 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
import org.sagebionetworks.bridge.models.assessments.HibernateAssessment;
import org.sagebionetworks.bridge.models.assessments.HibernateAssessmentResource;
import org.sagebionetworks.bridge.models.assessments.config.HibernateAssessmentConfig;
import org.sagebionetworks.bridge.models.demographics.Demographic;
import org.sagebionetworks.bridge.models.demographics.DemographicUser;
import org.sagebionetworks.bridge.models.demographics.DemographicValue;
import org.sagebionetworks.bridge.models.files.FileMetadata;
import org.sagebionetworks.bridge.models.files.FileRevision;
import org.sagebionetworks.bridge.models.organizations.HibernateOrganization;
Expand All @@ -137,9 +140,6 @@
import org.sagebionetworks.bridge.models.schedules2.adherence.weekly.WeeklyAdherenceReport;
import org.sagebionetworks.bridge.models.schedules2.timelines.TimelineMetadata;
import org.sagebionetworks.bridge.models.studies.Alert;
import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.studies.DemographicUser;
import org.sagebionetworks.bridge.models.studies.DemographicValue;
import org.sagebionetworks.bridge.redis.JedisOps;
import org.sagebionetworks.bridge.s3.S3Helper;
import org.sagebionetworks.bridge.spring.filters.MetricsFilter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import java.util.Optional;

import org.sagebionetworks.bridge.models.PagedResourceList;
import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.studies.DemographicUser;
import org.sagebionetworks.bridge.models.demographics.Demographic;
import org.sagebionetworks.bridge.models.demographics.DemographicUser;

/**
* Dao for demographic-related operations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.Optional;

import org.sagebionetworks.bridge.exceptions.EntityNotFoundException;
import org.sagebionetworks.bridge.models.studies.DemographicValuesValidationConfig;
import org.sagebionetworks.bridge.models.demographics.DemographicValuesValidationConfig;

public interface DemographicValidationDao {
public DemographicValuesValidationConfig saveDemographicValuesValidationConfig(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.Map;

import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.demographics.Demographic;

import com.fasterxml.jackson.core.type.TypeReference;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import org.sagebionetworks.bridge.dao.DemographicValidationDao;
import org.sagebionetworks.bridge.exceptions.EntityNotFoundException;
import org.sagebionetworks.bridge.models.studies.DemographicValuesValidationConfig;
import org.sagebionetworks.bridge.models.demographics.DemographicValuesValidationConfig;
import org.springframework.stereotype.Component;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.sagebionetworks.bridge.dynamodb;

import org.sagebionetworks.bridge.json.BridgeTypeName;
import org.sagebionetworks.bridge.models.studies.DemographicValuesValidationConfig;
import org.sagebionetworks.bridge.models.demographics.DemographicValuesValidationConfig;
import org.sagebionetworks.bridge.validators.DemographicValuesValidationType;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.sagebionetworks.bridge.json.DateTimeToLongSerializer;
import org.sagebionetworks.bridge.models.accounts.ParticipantVersion;
import org.sagebionetworks.bridge.models.accounts.SharingScope;
import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.demographics.Demographic;

@DynamoDBTable(tableName = "ParticipantVersion")
public class DynamoParticipantVersion implements ParticipantVersion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.Map;

import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.demographics.Demographic;

import com.fasterxml.jackson.core.type.TypeReference;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import org.sagebionetworks.bridge.hibernate.QueryBuilder.WhereClauseBuilder;
import org.sagebionetworks.bridge.models.PagedResourceList;
import org.sagebionetworks.bridge.models.SearchTermPredicate;
import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.studies.DemographicUser;
import org.sagebionetworks.bridge.models.demographics.Demographic;
import org.sagebionetworks.bridge.models.demographics.DemographicUser;
import org.springframework.stereotype.Component;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,27 @@

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.studies.DemographicUser;
import org.sagebionetworks.bridge.models.studies.DemographicUserAssessment;
import org.sagebionetworks.bridge.models.studies.DemographicValue;
import org.sagebionetworks.bridge.models.demographics.Demographic;
import org.sagebionetworks.bridge.models.demographics.DemographicUser;
import org.sagebionetworks.bridge.models.demographics.DemographicUserAssessment;
import org.sagebionetworks.bridge.models.demographics.DemographicValue;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;

/**
* Class used to deserialize from the mobile client v2 assessment JSON schema
* draft 7
* (https://github.com/Sage-Bionetworks/mobile-client-json/blob/00320defcb5c67873c501b5d99201fed6fdcd0e6/schemas/v2/AssessmentResultObject.json)
* and convert to the "normal" format. Throws JsonMappingException when the
* types are incorrect, but generally allows empty values.
* and convert to the "normal" format.
*/
public class DemographicUserAssessmentDeserializer extends JsonDeserializer<DemographicUserAssessment> {
@Override
Expand All @@ -33,95 +31,121 @@ public DemographicUserAssessment deserialize(JsonParser p, DeserializationContex
Map<String, Demographic> demographics = new ConcurrentHashMap<>();
DemographicUser demographicUser = new DemographicUser(null, null, null, null, demographics);
DemographicUserAssessment demographicUserAssessment = new DemographicUserAssessment(demographicUser);
JsonNode tree = p.readValueAsTree();
if (!tree.isObject()) {
throw new JsonMappingException(p, "assessment should be an object");

AssessmentResultObject assessmentResultObject = p.readValueAs(AssessmentResultObject.class);
if (assessmentResultObject.getStepHistory() != null) {
for (CollectionResultObject step : assessmentResultObject.getStepHistory()) {
if (step != null && step.getChildren() != null) {
for (AnswerResultObject answer : step.getChildren()) {
if (answer != null && answer.getIdentifier() != null && answer.getValue() != null) {
JsonNode value = answer.getValue();
List<DemographicValue> demographicValues = new ArrayList<>();
String categoryName = answer.getIdentifier();
Demographic demographic = new Demographic(null, demographicUser, categoryName, true,
demographicValues, null);
demographics.put(categoryName, demographic);

if (value.isObject()) {
Map<String, String> valueMap = BridgeObjectMapper.get()
.readerFor(new TypeReference<Map<String, String>>() {
}).readValue(value);
for (Map.Entry<String, String> entry : valueMap.entrySet()) {
demographicValues.add(new DemographicValue(entry.getKey(), entry.getValue()));
}
demographic.setMultipleSelect(true);
} else if (value.isArray()) {
List<String> valueArray = BridgeObjectMapper.get()
.readerFor(new TypeReference<List<String>>() {
}).readValue(value);
for (String valueString : valueArray) {
demographicValues.add(new DemographicValue(valueString));
}
demographic.setMultipleSelect(true);
} else {
DemographicValue singleValue = BridgeObjectMapper.get().treeToValue(value,
DemographicValue.class);
if (singleValue == null) {
// if it's null store the string null
singleValue = new DemographicValue((String) null);
}
demographicValues.add(singleValue);
demographic.setMultipleSelect(false);
}
if (answer.getAnswerType() != null && answer.getAnswerType().getUnit() != null) {
demographic.setUnits(answer.getAnswerType().getUnit());
}
}
}
}
}
}
if (!tree.hasNonNull("stepHistory")) {
return demographicUserAssessment;

return demographicUserAssessment;
}

public static class AssessmentResultObject {
private List<CollectionResultObject> stepHistory;

public List<CollectionResultObject> getStepHistory() {
return stepHistory;
}
JsonNode stepHistory = tree.get("stepHistory");
if (!stepHistory.isArray()) {
throw new JsonMappingException(p, "stepHistory field value should be an array");

public void setStepHistory(List<CollectionResultObject> stepHistory) {
this.stepHistory = stepHistory;
}
JsonNode resultCollection = null;
for (JsonNode element : stepHistory) {
if (element.hasNonNull("children")) {
resultCollection = element.get("children");
}
}

public static class CollectionResultObject {
private List<AnswerResultObject> children;

public List<AnswerResultObject> getChildren() {
return children;
}
if (resultCollection == null) {
return demographicUserAssessment;

public void setChildren(List<AnswerResultObject> children) {
this.children = children;
}
}

public static class AnswerResultObject {
private AnswerTypeMeasurement answerType;
private String identifier;
private JsonNode value;

public AnswerTypeMeasurement getAnswerType() {
return answerType;
}
if (!resultCollection.isArray()) {
throw new JsonMappingException(p, "children field value should be an array");

public void setAnswerType(AnswerTypeMeasurement answerType) {
this.answerType = answerType;
}
for (JsonNode answer : resultCollection) {
List<DemographicValue> demographicValues = new ArrayList<>();
Demographic demographic = new Demographic(null, demographicUser, null, true, demographicValues, null);
if (!answer.isObject()) {
throw new JsonMappingException(p, "each element in array children should be an object");
}

// get units from answerType
JsonNode answerType = answer.get("answerType");
if (answerType != null && answerType.hasNonNull("unit") && answerType.get("unit").isTextual()) {
demographic.setUnits(answerType.get("unit").textValue());
}
public String getIdentifier() {
return identifier;
}

// get identifier (categoryName)
if (!answer.hasNonNull("identifier")) {
throw new JsonMappingException(p,
"each object in array children should have non-null field named identifier");
}
JsonNode identifier = answer.get("identifier");
if (!identifier.isTextual()) {
throw new JsonMappingException(p, "field identifier should have value of type string");
}
String categoryName = identifier.textValue();
demographic.setCategoryName(categoryName);
public void setIdentifier(String identifier) {
this.identifier = identifier;
}

// get value
if (!answer.hasNonNull("value")) {
throw new JsonMappingException(p,
"each object in array children should have non-null field named value");
}
JsonNode value = answer.get("value");
if (value.isObject()) {
for (Iterator<Map.Entry<String, JsonNode>> iter = value.fields(); iter.hasNext();) {
Map.Entry<String, JsonNode> entry = iter.next();
if (!entry.getValue().isValueNode()) {
throw new JsonMappingException(p,
"when value is type object, none of its values should be container types");
}
demographicValues.add(new DemographicValue(entry.getKey(), valueNodeToString(entry.getValue())));
}
demographic.setMultipleSelect(true);
} else if (value.isArray()) {
for (JsonNode element : value) {
if (!element.isValueNode()) {
throw new JsonMappingException(p,
"when value is type array, none of its elements should be container types");
}
demographicValues.add(new DemographicValue(valueNodeToString(element)));
}
demographic.setMultipleSelect(true);
} else {
demographicValues.add(new DemographicValue(valueNodeToString(value)));
demographic.setMultipleSelect(false);
}
public JsonNode getValue() {
return value;
}

demographics.put(categoryName, demographic);
public void setValue(JsonNode value) {
this.value = value;
}
return demographicUserAssessment;
}

private String valueNodeToString(JsonNode value) throws JsonProcessingException {
if (value.isTextual()) {
// no quotations around the string
return value.textValue();
} else {
return BridgeObjectMapper.get().writeValueAsString(value);
public static class AnswerTypeMeasurement {
private String unit;

public String getUnit() {
return unit;
}

public void setUnit(String unit) {
this.unit = unit;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.io.IOException;

import org.sagebionetworks.bridge.models.studies.DemographicValue;
import org.sagebionetworks.bridge.models.demographics.DemographicValue;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import org.sagebionetworks.bridge.dynamodb.DynamoParticipantVersion;
import org.sagebionetworks.bridge.json.BridgeTypeName;
import org.sagebionetworks.bridge.models.BridgeEntity;
import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.demographics.Demographic;

/**
* Represents a de-identified snapshot of a study participant at a moment in time. This is used by Exporter 3.0 to
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sagebionetworks.bridge.models.studies;
package org.sagebionetworks.bridge.models.demographics;

import java.util.List;
import java.util.ListIterator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sagebionetworks.bridge.models.studies;
package org.sagebionetworks.bridge.models.demographics;

import java.util.Map;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sagebionetworks.bridge.models.studies;
package org.sagebionetworks.bridge.models.demographics;

import org.sagebionetworks.bridge.json.DemographicUserAssessmentDeserializer;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sagebionetworks.bridge.models.studies;
package org.sagebionetworks.bridge.models.demographics;

import javax.persistence.Embeddable;
import javax.validation.constraints.NotNull;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.sagebionetworks.bridge.models.studies;
package org.sagebionetworks.bridge.models.demographics;

import org.sagebionetworks.bridge.dynamodb.DynamoDemographicValuesValidationConfig;
import org.sagebionetworks.bridge.models.BridgeEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
import org.sagebionetworks.bridge.exceptions.InvalidEntityException;
import org.sagebionetworks.bridge.models.PagedResourceList;
import org.sagebionetworks.bridge.models.accounts.Account;
import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.studies.DemographicUser;
import org.sagebionetworks.bridge.models.studies.DemographicValue;
import org.sagebionetworks.bridge.models.studies.DemographicValuesValidationConfig;
import org.sagebionetworks.bridge.models.demographics.Demographic;
import org.sagebionetworks.bridge.models.demographics.DemographicUser;
import org.sagebionetworks.bridge.models.demographics.DemographicValue;
import org.sagebionetworks.bridge.models.demographics.DemographicValuesValidationConfig;
import org.sagebionetworks.bridge.validators.DemographicUserValidator;
import org.sagebionetworks.bridge.validators.DemographicValuesValidationConfigValidator;
import org.sagebionetworks.bridge.validators.DemographicValuesValidator;
Expand Down
Loading

0 comments on commit 8ef64fc

Please sign in to comment.