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

DataBiosphere / consent / #5772

29 Apr 2025 01:12PM UTC coverage: 79.983% (+0.5%) from 79.492%
#5772

push

web-flow
DT-1542: Refactor email sending service code (#2499)

172 of 179 new or added lines in 18 files covered. (96.09%)

12 existing lines in 2 files now uncovered.

10257 of 12824 relevant lines covered (79.98%)

0.8 hits per line

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

78.65
/src/main/java/org/broadinstitute/consent/http/models/Dataset.java
1
package org.broadinstitute.consent.http.models;
2

3
import com.google.gson.JsonArray;
4
import com.google.gson.JsonPrimitive;
5
import java.util.ArrayList;
6
import java.util.Date;
7
import java.util.HashSet;
8
import java.util.List;
9
import java.util.Objects;
10
import java.util.Optional;
11
import java.util.Set;
12
import org.apache.commons.lang3.StringUtils;
13
import org.broadinstitute.consent.http.models.dataset_registration_v1.ConsentGroup.AccessManagement;
14
import org.broadinstitute.consent.http.models.dataset_registration_v1.builder.DatasetRegistrationSchemaV1Builder;
15
import org.broadinstitute.consent.http.util.ConsentLogger;
16
import org.checkerframework.checker.nullness.qual.NonNull;
17

18
public class Dataset implements ConsentLogger {
19

20
  private Integer datasetId;
21

22
  private String objectId;
23

24
  private String name;
25

26
  // For backwards compatibility with DatasetDTO, this is an alias to the name property.
27
  private String datasetName;
28

29
  private Date createDate;
30

31
  private Integer createUserId;
32

33
  private Date updateDate;
34

35
  private Integer updateUserId;
36

37
  private Integer alias;
38

39
  private String datasetIdentifier;
40

41
  public DataUse dataUse;
42

43
  private String translatedDataUse;
44
  private Integer dacId;
45

46
  private Boolean deletable;
47

48
  private FileStorageObject nihInstitutionalCertificationFile;
49

50
  private Set<DatasetProperty> properties;
51

52
  List<String> propertyName;
53
  private Boolean dacApproval;
54

55
  private User createUser;
56

57
  private Integer studyId;
58

59
  private Study study;
60

61
  private Date indexedDate;
62

63
  public Dataset() {
1✔
64
  }
1✔
65

66
  public Dataset(Integer datasetId, String objectId, String name, Date createDate,
67
      Integer createUserId, Date updateDate, Integer updateUserId, Integer alias) {
×
68
    this.datasetId = datasetId;
×
69
    this.objectId = objectId;
×
70
    this.name = name;
×
71
    this.datasetName = name;
×
72
    this.createDate = createDate;
×
73
    this.createUserId = createUserId;
×
74
    this.updateDate = updateDate;
×
75
    this.updateUserId = updateUserId;
×
76
    this.alias = alias;
×
77
  }
×
78

79
  public Dataset(Integer datasetId, String objectId, String name, Date createDate, Integer alias) {
×
80
    this.datasetId = datasetId;
×
81
    this.objectId = objectId;
×
82
    this.name = name;
×
83
    this.datasetName = name;
×
84
    this.createDate = createDate;
×
85
    this.alias = alias;
×
86
  }
×
87

UNCOV
88
  public Dataset(Integer datasetId, String objectId, String name, Date createDate) {
×
UNCOV
89
    this.datasetId = datasetId;
×
UNCOV
90
    this.objectId = objectId;
×
UNCOV
91
    this.name = name;
×
UNCOV
92
    this.datasetName = name;
×
UNCOV
93
    this.createDate = createDate;
×
UNCOV
94
  }
×
95

96
  private static final String PREFIX = "DUOS-";
97

98
  public Dataset(String objectId) {
×
99
    this.objectId = objectId;
×
100
  }
×
101

102
  public Integer getDatasetId() {
103
    return datasetId;
1✔
104
  }
105

106
  public void setDatasetId(Integer datasetId) {
107
    this.datasetId = datasetId;
1✔
108
  }
1✔
109

110
  public String getObjectId() {
111
    return objectId;
×
112
  }
113

114
  public void setObjectId(String objectId) {
115
    this.objectId = objectId;
1✔
116
  }
1✔
117

118
  public String getName() {
119
    return name;
1✔
120
  }
121

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

126
  public String getDatasetName() {
127
    return datasetName;
1✔
128
  }
129

130
  public void setDatasetName(String datasetName) {
131
    this.datasetName = datasetName;
1✔
132
  }
1✔
133

134
  public Date getCreateDate() {
135
    return createDate;
×
136
  }
137

138
  public void setCreateDate(Date createDate) {
139
    this.createDate = createDate;
1✔
140
  }
1✔
141

142
  public Integer getCreateUserId() {
143
    return createUserId;
1✔
144
  }
145

146
  public void setCreateUserId(Integer createUserId) {
147
    this.createUserId = createUserId;
1✔
148
  }
1✔
149

150
  public Date getUpdateDate() {
151
    return updateDate;
1✔
152
  }
153

154
  public void setUpdateDate(Date updateDate) {
155
    this.updateDate = updateDate;
1✔
156
  }
1✔
157

158
  public Integer getUpdateUserId() {
159
    return updateUserId;
1✔
160
  }
161

162
  public void setUpdateUserId(Integer updateUserId) {
163
    this.updateUserId = updateUserId;
1✔
164
  }
1✔
165

166
  public Set<DatasetProperty> getProperties() {
167
    return properties;
1✔
168
  }
169

170
  public List<String> getPropertyName() {
171
    return propertyName;
×
172
  }
173

174

175
  public void setProperties(Set<DatasetProperty> properties) {
176
    this.properties = properties;
1✔
177
  }
1✔
178

179
  public void addProperty(DatasetProperty property) {
180
    if (Objects.isNull(this.properties)) {
1✔
181
      this.properties = new HashSet<>();
1✔
182
    }
183
    this.properties.add(property);
1✔
184
  }
1✔
185

186
  public Boolean getDacApproval() {
187
    return dacApproval;
1✔
188
  }
189

190
  public void setDacApproval(Boolean dacApproval) {
191
    this.dacApproval = dacApproval;
1✔
192
  }
1✔
193

194
  public Integer getAlias() {
195
    return alias;
1✔
196
  }
197

198
  public void setAlias(Integer alias) {
199
    this.alias = alias;
1✔
200
  }
1✔
201

202
  public DataUse getDataUse() {
203
    return dataUse;
1✔
204
  }
205

206
  public void setDataUse(DataUse dataUse) {
207
    this.dataUse = dataUse;
1✔
208
  }
1✔
209

210
  public void setDatasetIdentifier() {
211
    this.datasetIdentifier = parseAliasToIdentifier(this.getAlias());
1✔
212
  }
1✔
213

214
  public String getDatasetIdentifier() {
215
    if (Objects.isNull(this.getAlias())) {
1✔
216
      return null;
1✔
217
    }
218

219
    return parseAliasToIdentifier(this.getAlias());
1✔
220
  }
221

222
  public static String parseAliasToIdentifier(Integer alias) {
223
    return PREFIX + StringUtils.leftPad(alias.toString(), 6, "0");
1✔
224
  }
225

226
  public static Integer parseIdentifierToAlias(String identifier) throws IllegalArgumentException {
227
    try {
228
      String givenPrefix = identifier.substring(0, PREFIX.length());
1✔
229
      if (!givenPrefix.equals(PREFIX)) {
1✔
230
        throw new IllegalArgumentException("Invalid prefix.");
1✔
231
      }
232

233
      String aliasAsString = identifier.substring(PREFIX.length()); // cut off DUOS-
1✔
234
      return Integer.parseInt(aliasAsString); // parse remaining as integer
1✔
235
    } catch (Exception e) {
1✔
236
      throw new IllegalArgumentException(
1✔
237
          "Could not parse identifier (" + identifier + "). Proper format: " + PREFIX + "XXXXXX");
238
    }
239
  }
240

241
  public Integer getDacId() {
242
    return dacId;
1✔
243
  }
244

245
  public void setDacId(Integer dacId) {
246
    this.dacId = dacId;
1✔
247
  }
1✔
248

249
  public String getTranslatedDataUse() {
250
    return translatedDataUse;
1✔
251
  }
252

253
  public void setTranslatedDataUse(String translatedDataUse) {
254
    this.translatedDataUse = translatedDataUse;
1✔
255
  }
1✔
256

257
  public Boolean getDeletable() {
258
    return deletable;
1✔
259
  }
260

261
  public void setDeletable(Boolean deletable) {
262
    this.deletable = deletable;
1✔
263
  }
1✔
264

265
  /**
266
   * Checks if the Dataset matches a raw search query. Searches on all dataset properties and some
267
   * data use properties. Has optional parameter accessManagement which will search datasets on both
268
   * the raw search query and the access management type.
269
   *
270
   * @param query            Raw string query
271
   * @param accessManagement One of controlled, open, or external
272
   * @return if the Dataset matched query
273
   */
274

275
  // TODO: investigate whether we can try to coerce getPropertyValue to a boolean instead of comparing strings
276
  public boolean isDatasetMatch(@NonNull String query, AccessManagement accessManagement) {
277
    String lowerCaseQuery = query.toLowerCase();
1✔
278
    List<String> queryTerms = List.of(lowerCaseQuery.split("\\s+"));
1✔
279

280
    List<String> matchTerms = new ArrayList<>();
1✔
281
    matchTerms.add(this.getName());
1✔
282
    matchTerms.add(this.getDatasetIdentifier());
1✔
283

284
    if (Objects.nonNull(getProperties()) && !getProperties().isEmpty()) {
1✔
285
      Optional<DatasetProperty> accessManagementProp = getProperties()
1✔
286
          .stream()
1✔
287
          .filter((dp) -> Objects.nonNull(dp.getPropertyValue()))
1✔
288
          .filter((dp) -> Objects.equals(dp.getPropertyName(), "Access Management"))
1✔
289
          .findFirst();
1✔
290

291
      if (accessManagementProp.isEmpty()) {
1✔
292
        if (accessManagement.equals(AccessManagement.OPEN)) {
1✔
293
          return false;
×
294
        }
295
      } else if (!accessManagement.toString()
1✔
296
          .equals(accessManagementProp.get().getPropertyValueAsString())) {
1✔
297
        return false;
1✔
298
      }
299

300
      List<String> propVals = getProperties()
1✔
301
          .stream()
1✔
302
          .filter((dp) -> Objects.nonNull(dp.getPropertyValue()))
1✔
303
          .map(DatasetProperty::getPropertyValueAsString)
1✔
304
          .map(String::toLowerCase)
1✔
305
          .toList();
1✔
306
      matchTerms.addAll(propVals);
1✔
307
    }
308

309
    if (Objects.nonNull(dataUse)) {
1✔
310
      if (Objects.nonNull(dataUse.getEthicsApprovalRequired())
1✔
311
          && dataUse.getEthicsApprovalRequired()) {
1✔
312
        matchTerms.add("irb");
1✔
313
      }
314

315
      if (Objects.nonNull(dataUse.getCollaboratorRequired())
1✔
316
          && dataUse.getCollaboratorRequired()) {
1✔
317
        matchTerms.add("collaborator");
1✔
318
      }
319

320
      if (Objects.nonNull(dataUse.getDiseaseRestrictions())) {
1✔
321
        matchTerms.addAll(dataUse.getDiseaseRestrictions());
1✔
322
      }
323
    }
324

325
    return queryTerms
1✔
326
        .stream()
1✔
327
        .filter(Objects::nonNull)
1✔
328
        // all terms must match at least one thing
329
        .allMatch((q) ->
1✔
330
            matchTerms
1✔
331
                .stream()
1✔
332
                .filter(Objects::nonNull)
1✔
333
                .map(String::toLowerCase)
1✔
334
                .anyMatch(
1✔
335
                    (t) -> t.contains(q))
1✔
336
        );
337
  }
338

339
  public Study getStudy() {
340
    return study;
1✔
341
  }
342

343
  public void setStudy(Study study) {
344
    this.study = study;
1✔
345
  }
1✔
346

347
  public Integer getStudyId() {
348
    return studyId;
×
349
  }
350

351
  public void setStudyId(Integer studyId) {
352
    this.studyId = studyId;
1✔
353
  }
1✔
354

355
  public Date getIndexedDate() {
356
    return indexedDate;
1✔
357
  }
358

359
  public void setIndexedDate(Date indexedDate) {
360
    this.indexedDate = indexedDate;
1✔
361
  }
1✔
362

363
  /**
364
   * Determine if the user is a dataset/study creator
365
   *
366
   * @param user User
367
   * @return User is a creator of the dataset/study
368
   */
369
  public boolean isCustodian(User user) {
370
    if (getStudy() != null && getStudy().getProperties() != null) {
1✔
371
      Optional<StudyProperty> dataCustodians = getStudy()
1✔
372
          .getProperties()
1✔
373
          .stream()
1✔
374
          .filter(p -> p.getKey().equals(DatasetRegistrationSchemaV1Builder.dataCustodianEmail))
1✔
375
          .findFirst();
1✔
376
      if (dataCustodians.isPresent()) {
1✔
377
        JsonArray jsonArray = (JsonArray) dataCustodians.get().getValue();
1✔
378
        return jsonArray.contains(new JsonPrimitive(user.getEmail()));
1✔
379
      } else {
380
        logWarn(
×
381
            "No data custodians found for dataset: %s".formatted(getDatasetIdentifier()));
×
382
      }
383
    } else {
×
384
      logWarn(
1✔
385
          "No study properties found for dataset: %s".formatted(getDatasetIdentifier()));
1✔
386
    }
387
    return false;
1✔
388
  }
389

390
  public boolean isCreator(User user) {
391
    if (Objects.equals(user.getUserId(), getCreateUserId())) {
1✔
392
      return true;
1✔
393
    }
394
    return getStudy() != null && Objects.equals(user.getUserId(),
1✔
395
        getStudy().getCreateUserId());
1✔
396
  }
397

398
  @Override
399
  public boolean equals(Object o) {
400
    if (this == o) {
1✔
401
      return true;
1✔
402
    }
403
    if (o == null || getClass() != o.getClass()) {
1✔
404
      return false;
×
405
    }
406
    Dataset dataset = (Dataset) o;
1✔
407
    return com.google.common.base.Objects.equal(datasetId, dataset.datasetId);
1✔
408
  }
409

410
  @Override
411
  public int hashCode() {
412
    return com.google.common.base.Objects.hashCode(datasetId);
1✔
413
  }
414

415
  public FileStorageObject getNihInstitutionalCertificationFile() {
416
    return nihInstitutionalCertificationFile;
1✔
417
  }
418

419
  public void setNihInstitutionalCertificationFile(
420
      FileStorageObject nihInstitutionalCertificationFile) {
421
    this.nihInstitutionalCertificationFile = nihInstitutionalCertificationFile;
1✔
422
  }
1✔
423

424
  public User getCreateUser() {
425
    return createUser;
1✔
426
  }
427

428
  public void setCreateUser(User createUser) {
429
    this.createUser = createUser;
1✔
430
  }
1✔
431

432
}
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