• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DataBiosphere / consent / #5845

05 May 2025 01:40PM UTC coverage: 78.768% (-0.004%) from 78.772%
#5845

push

web-flow
DT-1472: Populate eRA Commons Id on DAR submission (#2511)

7 of 8 new or added lines in 3 files covered. (87.5%)

1 existing line in 1 file now uncovered.

10080 of 12797 relevant lines covered (78.77%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.64
/src/main/java/org/broadinstitute/consent/http/models/DataAccessRequest.java
1
package org.broadinstitute.consent.http.models;
2

3
import com.fasterxml.jackson.annotation.JsonInclude;
4
import com.fasterxml.jackson.annotation.JsonInclude.Include;
5
import com.fasterxml.jackson.annotation.JsonProperty;
6
import com.google.common.base.CaseFormat;
7
import com.google.gson.Gson;
8
import com.google.gson.GsonBuilder;
9
import com.google.gson.JsonObject;
10
import com.google.gson.JsonPrimitive;
11
import com.google.gson.JsonSerializer;
12
import com.google.gson.reflect.TypeToken;
13
import java.lang.reflect.Type;
14
import java.sql.Timestamp;
15
import java.util.ArrayList;
16
import java.util.Date;
17
import java.util.HashMap;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Objects;
21
import java.util.concurrent.TimeUnit;
22
import java.util.stream.Collectors;
23
import java.util.stream.Stream;
24

25
@JsonInclude(Include.NON_NULL)
26
public class DataAccessRequest {
27

28
  public static final long EXPIRATION_DURATION_MILLIS = TimeUnit.DAYS.toMillis(365);
1✔
29

30
  @JsonProperty
31
  public Integer id;
32

33
  @JsonProperty
34
  public String referenceId;
35

36
  @JsonProperty
37
  public Integer collectionId;
38

39
  @JsonProperty
40
  public String parentId;
41

42
  @JsonProperty
43
  public DataAccessRequestData data;
44

45
  @JsonProperty
46
  public String darCode;
47

48
  @JsonProperty
1✔
49
  public Boolean draft = true;
1✔
50

51
  @JsonProperty
1✔
52
  public Boolean expired = false;
1✔
53

54
  @JsonProperty
55
  public Timestamp expiresAt;
56

57
  @JsonProperty
58
  public Integer userId;
59

60
  @JsonProperty
61
  public Timestamp createDate;
62

63
  /*
64
   * Legacy property on DARs. Used to display the sort order for a DAR. In practice, this also
65
   * functions as the Update Date. See also https://broadinstitute.atlassian.net/browse/DUOS-728
66
   */
67
  @JsonProperty
68
  public Timestamp sortDate;
69

70
  @JsonProperty
71
  public Timestamp submissionDate;
72

73
  @JsonProperty
74
  public Timestamp updateDate;
75
  @JsonProperty
76
  public List<Integer> datasetIds;
77
  @JsonProperty
78
  private Map<Integer, Election> elections;
79
  @JsonProperty
80
  private String eraCommonsId;
81

82
  public DataAccessRequest() {
1✔
83
    this.elections = new HashMap<>();
1✔
84
  }
1✔
85

86
  public static boolean isCanceled(DataAccessRequest dar) {
87
    return
1✔
88
        Objects.nonNull(dar) &&
1✔
89
            Objects.nonNull(dar.getData()) &&
1✔
90
            Objects.nonNull(dar.getData().getStatus()) &&
1✔
91
            dar.getData().getStatus().equalsIgnoreCase("canceled");
1✔
92
  }
93

94
  public Integer getId() {
95
    return id;
1✔
96
  }
97

98
  public void setId(Integer id) {
99
    this.id = id;
1✔
100
  }
1✔
101

102
  public String getReferenceId() {
103
    return referenceId;
1✔
104
  }
105

106
  public void setReferenceId(String referenceId) {
107
    this.referenceId = referenceId;
1✔
108
  }
1✔
109

110
  public Integer getCollectionId() {
111
    return collectionId;
1✔
112
  }
113

114
  public void setCollectionId(Integer collectionId) {
115
    this.collectionId = collectionId;
1✔
116
  }
1✔
117

118
  public String getParentId() {
119
    return parentId;
1✔
120
  }
121

122
  public void setParentId(String parentId) {
123
    this.parentId = parentId;
1✔
124
  }
1✔
125

126
  public DataAccessRequestData getData() {
127
    return data;
1✔
128
  }
129

130
  public void setData(DataAccessRequestData data) {
131
    this.data = data;
1✔
132
  }
1✔
133

134
  public Boolean getDraft() {
135
    return draft;
1✔
136
  }
137

138
  public boolean getExpired() {
139
    return expired;
1✔
140
  }
141

142
  public Timestamp getExpiresAt() {
143
    return expiresAt;
1✔
144
  }
145

146
  public Integer getUserId() {
147
    return userId;
1✔
148
  }
149

150
  public void setUserId(Integer userId) {
151
    this.userId = userId;
1✔
152
  }
1✔
153

154
  public Date getCreateDate() {
155
    return createDate;
1✔
156
  }
157

158
  public void setCreateDate(Timestamp createDate) {
159
    this.createDate = createDate;
1✔
160
  }
1✔
161

162
  public Date getSortDate() {
163
    return sortDate;
1✔
164
  }
165

166
  public void setSortDate(Timestamp sortDate) {
167
    this.sortDate = sortDate;
1✔
168
  }
1✔
169

170
  public Timestamp getSubmissionDate() {
171
    return submissionDate;
1✔
172
  }
173

174
  public void setSubmissionDate(Timestamp submissionDate) {
175
    this.submissionDate = submissionDate;
1✔
176
    draft = submissionDate == null;
1✔
177
    expired = submissionDate != null
1✔
178
        && submissionDate.before(
1✔
179
        new Timestamp(System.currentTimeMillis() - EXPIRATION_DURATION_MILLIS));
1✔
180
    expiresAt = (submissionDate != null) ? new Timestamp(
1✔
181
        submissionDate.getTime() + EXPIRATION_DURATION_MILLIS) : null;
1✔
182
  }
1✔
183

184
  public Timestamp getUpdateDate() {
185
    return updateDate;
1✔
186
  }
187

188
  public void setUpdateDate(Timestamp updateDate) {
189
    this.updateDate = updateDate;
1✔
190
  }
1✔
191

192
  public Map<Integer, Election> getElections() {
193
    return elections;
1✔
194
  }
195

196
  public void setElections(Map<Integer, Election> elections) {
197
    this.elections = elections;
×
198
  }
×
199

200
  public void addElection(Election election) {
201
    if (Objects.isNull(elections)) {
1✔
202
      this.setElections(new HashMap<>());
×
203
    }
204
    if (Objects.nonNull(election)) {
1✔
205
      Integer electionId = election.getElectionId();
1✔
206
      Election savedRecord = elections.get(electionId);
1✔
207
      if (Objects.isNull(savedRecord)) {
1✔
208
        elections.put(electionId, election);
1✔
209
      }
210
    }
211
  }
1✔
212

213
  public List<Integer> getDatasetIds() {
214
    if (Objects.isNull(datasetIds)) {
1✔
215
      return List.of();
1✔
216
    }
217
    return datasetIds;
1✔
218
  }
219

220
  public void setDatasetIds(List<Integer> datasetIds) {
221
    this.datasetIds = datasetIds;
1✔
222
  }
1✔
223

224
  public void addDatasetId(Integer id) {
225
    if (Objects.isNull(datasetIds)) {
1✔
226
      datasetIds = new ArrayList<>();
1✔
227
    }
228
    if (!datasetIds.contains(id)) {
1✔
229
      datasetIds.add(id);
1✔
230
    }
231
  }
1✔
232

233
  public void addDatasetIds(List<Integer> ids) {
234
    if (Objects.isNull(datasetIds)) {
1✔
235
      datasetIds = new ArrayList<>();
1✔
236
    }
237
    if (Objects.nonNull(ids) && !ids.isEmpty()) {
1✔
238
      datasetIds = Stream.of(datasetIds, ids)
1✔
239
          .flatMap(List::stream)
1✔
240
          .distinct()
1✔
241
          .collect(Collectors.toList());
1✔
242
    }
243
  }
1✔
244

245
  public void setDarCode(String darCode) {
246
    this.darCode = darCode;
1✔
247
  }
1✔
248

249
  public String getDarCode() {
250
    return darCode;
1✔
251
  }
252

253
  public String getEraCommonsId() {
254
    return eraCommonsId;
1✔
255
  }
256

257
  public void setEraCommonsId(String eraCommonsId) {
258
    this.eraCommonsId = eraCommonsId;
1✔
259
  }
1✔
260

261

262
  /**
263
   * Merges the DAR and the DAR Data into a single Map Ignores a series of deprecated keys Null
264
   * values are ignored by default
265
   *
266
   * @return Map<String, Object> Dar in simple map format
267
   */
268
  public Map<String, Object> convertToSimplifiedDar() {
269
    // Serialize dates/timestamps as longs, but do not deserialize longs into dates so we can
270
    // output long values in the final result.
271
    Gson gson = new GsonBuilder()
1✔
272
        .registerTypeAdapter(Date.class,
1✔
273
            (JsonSerializer<Date>) (date, type, jsonSerializationContext) -> new JsonPrimitive(
×
274
                date.getTime()))
×
275
        .registerTypeAdapter(Timestamp.class,
1✔
276
            (JsonSerializer<Timestamp>) (timestamp, type, jsonSerializationContext) -> new JsonPrimitive(
×
277
                timestamp.getTime()))
×
278
        .create();
1✔
279
    DataAccessRequestData dataCopy = this.getData();
1✔
280
    this.setData(null);
1✔
281

282
    String serializedDar = gson.toJson(shallowCopy(this));
1✔
283
    JsonObject dar = gson.fromJson(serializedDar, JsonObject.class);
1✔
284

285
    String serializedDarData = gson.toJson(dataCopy);
1✔
286
    JsonObject darData = gson.fromJson(serializedDarData, JsonObject.class);
1✔
287

288
    DataAccessRequestData.DEPRECATED_PROPS.forEach(darData::remove);
1✔
289
    for (String dataKey : darData.keySet()) {
1✔
290
      String camelCasedDataKey =
291
          dataKey.contains("_")
1✔
292
              ? CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, dataKey)
×
293
              : dataKey;
1✔
294
      if (!dar.has(camelCasedDataKey)) {
1✔
295
        dar.add(camelCasedDataKey, darData.get(dataKey));
1✔
296
      }
297
    }
1✔
298
    Type darMapType = new TypeToken<Map<String, Object>>() {
1✔
299
    }.getType();
1✔
300
    return gson.fromJson(dar.toString(), darMapType);
1✔
301
  }
302

303
  public boolean requiresManualReview() {
304
    return
1✔
305
        Objects.nonNull(this.getData()) && (
1✔
306
            (Objects.nonNull(this.getData().getPoa()) && this.getData().getPoa()) ||
1✔
307
                (Objects.nonNull(this.getData().getPopulation()) && this.getData().getPopulation())
1✔
308
                ||
309
                (Objects.nonNull(this.getData().getOther()) && this.getData().getOther()) ||
1✔
310
                (Objects.nonNull(this.getData().getOtherText()) && !this.getData().getOtherText()
1✔
311
                    .isBlank()) ||
1✔
312
                (Objects.nonNull(this.getData().getIllegalBehavior()) && this.getData()
1✔
313
                    .getIllegalBehavior()) ||
1✔
314
                (Objects.nonNull(this.getData().getAddiction()) && this.getData().getAddiction()) ||
1✔
315
                (Objects.nonNull(this.getData().getSexualDiseases()) && this.getData()
1✔
316
                    .getSexualDiseases()) ||
1✔
317
                (Objects.nonNull(this.getData().getStigmatizedDiseases()) && this.getData()
1✔
318
                    .getStigmatizedDiseases()) ||
1✔
319
                (Objects.nonNull(this.getData().getVulnerablePopulation()) && this.getData()
1✔
320
                    .getVulnerablePopulation()) ||
1✔
321
                (Objects.nonNull(this.getData().getPopulationMigration()) && this.getData()
1✔
322
                    .getPopulationMigration()) ||
1✔
323
                (Objects.nonNull(this.getData().getPsychiatricTraits()) && this.getData()
1✔
324
                    .getPsychiatricTraits()) ||
1✔
325
                (Objects.nonNull(this.getData().getNotHealth()) && this.getData().getNotHealth())
1✔
326
        );
327
  }
328

329
  /**
330
   * Make a shallow copy of the dar. This is mostly a workaround for problems serializing dates when
331
   * calling Gson.toJson on `this`
332
   *
333
   * @param dar DataAccessRequest
334
   * @return Shallow copy of DataAccessRequest
335
   */
336
  private Map<String, Object> shallowCopy(DataAccessRequest dar) {
337
    Map<String, Object> copy = new HashMap<>();
1✔
338
    if (Objects.nonNull(dar.getCreateDate())) {
1✔
339
      copy.put("createDate", dar.getCreateDate().getTime());
1✔
340
    }
341
    if (Objects.nonNull(dar.getDraft())) {
1✔
342
      copy.put("draft", dar.getDraft());
1✔
343
    }
344
    copy.put("expired", dar.getExpired());
1✔
345
    copy.put("expiredAt", dar.getExpiresAt());
1✔
346
    if (Objects.nonNull(dar.getId())) {
1✔
347
      copy.put("id", dar.getId());
1✔
348
    }
349
    if (Objects.nonNull(dar.getReferenceId())) {
1✔
350
      copy.put("referenceId", dar.getReferenceId());
1✔
351
    }
352
    if (Objects.nonNull(dar.getSortDate())) {
1✔
353
      copy.put("sortDate", dar.getSortDate().getTime());
1✔
354
    }
355
    if (Objects.nonNull(dar.getSubmissionDate())) {
1✔
356
      copy.put("submissionDate", dar.getSubmissionDate().getTime());
×
357
    }
358
    if (Objects.nonNull(dar.getUpdateDate())) {
1✔
359
      copy.put("updateDate", dar.getUpdateDate().getTime());
1✔
360
    }
361
    if (Objects.nonNull(dar.getUserId())) {
1✔
362
      copy.put("userId", dar.getUserId());
1✔
363
    }
364
    if (Objects.nonNull(dar.getCollectionId())) {
1✔
365
      copy.put("collectionId", dar.getCollectionId());
1✔
366
    }
367
    if (Objects.nonNull(dar.getDatasetIds())) {
1✔
368
      copy.put("datasetIds", dar.getDatasetIds());
1✔
369
    }
370
    if (Objects.nonNull(dar.getParentId())) {
1✔
371
      copy.put("parentId", dar.getParentId());
×
372
    }
373
    if (Objects.nonNull(dar.getDarCode())) {
1✔
374
      copy.put("darCode", dar.getDarCode());
×
375
    }
376
    if (dar.getEraCommonsId() != null) {
1✔
NEW
377
      copy.put("eraCommonsId", dar.getEraCommonsId());
×
378
    }
379
    return copy;
1✔
380
  }
381
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc