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

IQSS / dataverse / #24468

05 Feb 2025 03:21PM UTC coverage: 22.788% (+0.04%) from 22.752%
#24468

Pull #10790

github

web-flow
Merge b078516cf into aebec0536
Pull Request #10790: fix: issues in exporters and citations for PermaLink/non-DOI PIDs

51 of 69 new or added lines in 7 files covered. (73.91%)

1 existing line in 1 file now uncovered.

19949 of 87542 relevant lines covered (22.79%)

0.23 hits per line

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

35.09
/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java
1
package edu.harvard.iq.dataverse.util.json;
2

3
import edu.harvard.iq.dataverse.*;
4
import edu.harvard.iq.dataverse.authorization.DataverseRole;
5
import edu.harvard.iq.dataverse.authorization.groups.impl.maildomain.MailDomainGroup;
6
import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUser;
7
import edu.harvard.iq.dataverse.api.Util;
8
import edu.harvard.iq.dataverse.authorization.Permission;
9
import edu.harvard.iq.dataverse.authorization.RoleAssigneeDisplayInfo;
10
import edu.harvard.iq.dataverse.authorization.groups.impl.explicit.ExplicitGroup;
11
import edu.harvard.iq.dataverse.authorization.groups.impl.ipaddress.IpGroup;
12
import edu.harvard.iq.dataverse.authorization.groups.impl.ipaddress.ip.IpAddress;
13
import edu.harvard.iq.dataverse.authorization.groups.impl.ipaddress.ip.IpAddressRange;
14
import edu.harvard.iq.dataverse.authorization.groups.impl.shib.ShibGroup;
15
import edu.harvard.iq.dataverse.authorization.providers.AuthenticationProviderRow;
16
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
17
import edu.harvard.iq.dataverse.authorization.users.User;
18
import edu.harvard.iq.dataverse.branding.BrandingUtil;
19
import edu.harvard.iq.dataverse.dataaccess.DataAccess;
20
import edu.harvard.iq.dataverse.dataset.DatasetUtil;
21
import edu.harvard.iq.dataverse.datavariable.CategoryMetadata;
22
import edu.harvard.iq.dataverse.datavariable.DataVariable;
23
import edu.harvard.iq.dataverse.datavariable.SummaryStatistic;
24
import edu.harvard.iq.dataverse.datavariable.VarGroup;
25
import edu.harvard.iq.dataverse.datavariable.VariableCategory;
26
import edu.harvard.iq.dataverse.datavariable.VariableMetadata;
27
import edu.harvard.iq.dataverse.datavariable.VariableRange;
28
import edu.harvard.iq.dataverse.dataverse.featured.DataverseFeaturedItem;
29
import edu.harvard.iq.dataverse.license.License;
30
import edu.harvard.iq.dataverse.globus.FileDetailsHolder;
31
import edu.harvard.iq.dataverse.harvest.client.HarvestingClient;
32
import edu.harvard.iq.dataverse.privateurl.PrivateUrl;
33
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
34
import edu.harvard.iq.dataverse.util.BundleUtil;
35
import edu.harvard.iq.dataverse.util.DatasetFieldWalker;
36
import static edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder.jsonObjectBuilder;
37

38
import edu.harvard.iq.dataverse.workflow.Workflow;
39
import edu.harvard.iq.dataverse.workflow.step.WorkflowStepData;
40

41
import java.util.*;
42
import jakarta.json.Json;
43
import jakarta.json.JsonArrayBuilder;
44
import jakarta.json.JsonObjectBuilder;
45

46
import java.util.function.BiConsumer;
47
import java.util.function.BinaryOperator;
48
import java.util.function.Function;
49
import java.util.function.Supplier;
50
import java.util.logging.Logger;
51
import java.util.stream.Collector;
52
import java.util.stream.Collectors;
53
import static java.util.stream.Collectors.toList;
54

55
import jakarta.ejb.EJB;
56
import jakarta.ejb.Singleton;
57
import jakarta.json.JsonArray;
58
import jakarta.json.JsonObject;
59
import java.util.function.Predicate;
60

61
/**
62
 * Convert objects to Json.
63
 *
64
 * @author michael
65
 */
66
@Singleton
67
public class JsonPrinter {
68

69
    private static final Logger logger = Logger.getLogger(JsonPrinter.class.getCanonicalName());
1✔
70

71
    @EJB
72
    static SettingsServiceBean settingsService;
73

74
    @EJB
75
    static DatasetFieldServiceBean datasetFieldService;
76

77
    public static void injectSettingsService(SettingsServiceBean ssb, DatasetFieldServiceBean dfsb) {
78
            settingsService = ssb;
1✔
79
            datasetFieldService = dfsb;
1✔
80
    }
1✔
81

82
    public JsonPrinter() {
×
83

84
    }
×
85

86
    public static final BriefJsonPrinter brief = new BriefJsonPrinter();
1✔
87

88
    public static JsonArrayBuilder asJsonArray(Collection<String> strings) {
89
        JsonArrayBuilder arr = Json.createArrayBuilder();
1✔
90
        for (String s : strings) {
1✔
91
            arr.add(s);
1✔
92
        }
1✔
93
        return arr;
1✔
94
    }
95

96
    public static JsonObjectBuilder json(User u) {
97
        RoleAssigneeDisplayInfo displayInfo = u.getDisplayInfo();
×
98
        return jsonObjectBuilder()
×
99
                .add("identifier", u.getIdentifier())
×
100
                .add("displayInfo", jsonObjectBuilder()
×
101
                        .add("Title", displayInfo.getTitle())
×
102
                        .add("email", displayInfo.getEmailAddress()));
×
103
    }
104

105
    public static JsonObjectBuilder json(AuthenticatedUser authenticatedUser) {
106
        NullSafeJsonBuilder builder = jsonObjectBuilder()
×
107
            .add("id", authenticatedUser.getId())
×
108
            .add("identifier", authenticatedUser.getIdentifier())
×
109
            .add("displayName", authenticatedUser.getDisplayInfo().getTitle())
×
110
            .add("firstName", authenticatedUser.getFirstName())
×
111
            .add("lastName", authenticatedUser.getLastName())
×
112
            .add("email", authenticatedUser.getEmail())
×
113
            .add("superuser", authenticatedUser.isSuperuser())
×
114
            .add("deactivated", authenticatedUser.isDeactivated())
×
115
            .add("deactivatedTime", authenticatedUser.getDeactivatedTime())
×
116
            .add("affiliation", authenticatedUser.getAffiliation())
×
117
            .add("position", authenticatedUser.getPosition())
×
118
            .add("persistentUserId", authenticatedUser.getAuthenticatedUserLookup().getPersistentUserId())
×
119
            .add("emailLastConfirmed", authenticatedUser.getEmailConfirmed())
×
120
            .add("createdTime", authenticatedUser.getCreatedTime())
×
121
            .add("lastLoginTime", authenticatedUser.getLastLoginTime())
×
122
            .add("lastApiUseTime", authenticatedUser.getLastApiUseTime())
×
123
            .add("authenticationProviderId", authenticatedUser.getAuthenticatedUserLookup().getAuthenticationProviderId());
×
124
        return builder;
×
125
    }
126

127
    public static JsonObjectBuilder json(RoleAssignment ra) {
128
        return jsonObjectBuilder()
1✔
129
                .add("id", ra.getId())
1✔
130
                .add("assignee", ra.getAssigneeIdentifier())
1✔
131
                .add("roleId", ra.getRole().getId())
1✔
132
                .add("_roleAlias", ra.getRole().getAlias())
1✔
133
                .add("privateUrlToken", ra.getPrivateUrlToken())
1✔
134
                .add("definitionPointId", ra.getDefinitionPoint().getId());
1✔
135
    }
136

137
    public static JsonArrayBuilder json(Set<Permission> permissions) {
138
        JsonArrayBuilder bld = Json.createArrayBuilder();
×
139
        permissions.forEach(p -> bld.add(p.name()));
×
140
        return bld;
×
141
    }
142

143
    public static JsonObjectBuilder json(DatasetLock lock) {
144
        return jsonObjectBuilder()
×
145
                .add("lockType", lock.getReason().toString())
×
146
                .add("date", lock.getStartTime().toString())
×
147
                .add("user", lock.getUser().getUserIdentifier())
×
148
                .add("dataset", lock.getDataset().getGlobalId().asString())
×
149
                .add("message", lock.getInfo());
×
150
    }
151

152
    public static JsonObjectBuilder json( RoleAssigneeDisplayInfo d ) {
153
        return jsonObjectBuilder()
×
154
                .add("title", d.getTitle())
×
155
                .add("email", d.getEmailAddress())
×
156
                .add("affiliation", d.getAffiliation());
×
157
    }
158

159
    public static JsonObjectBuilder json(IpGroup grp) {
160
         // collect single addresses
161
        List<String> singles = grp.getRanges().stream().filter( IpAddressRange::isSingleAddress )
1✔
162
                                .map( IpAddressRange::getBottom )
1✔
163
                                .map( IpAddress::toString ).collect(toList());
1✔
164
        // collect "real" ranges
165
        List<List<String>> ranges = grp.getRanges().stream().filter( rng -> !rng.isSingleAddress() )
1✔
166
                                .map( rng -> Arrays.asList(rng.getBottom().toString(), rng.getTop().toString()) )
1✔
167
                                .collect(toList());
1✔
168

169
        JsonObjectBuilder bld = jsonObjectBuilder()
1✔
170
                .add("alias", grp.getPersistedGroupAlias() )
1✔
171
                .add("identifier", grp.getIdentifier())
1✔
172
                .add("id", grp.getId() )
1✔
173
                .add("name", grp.getDisplayName() )
1✔
174
                .add("description", grp.getDescription() );
1✔
175

176
        if ( ! singles.isEmpty() ) {
1✔
177
            bld.add("addresses", asJsonArray(singles) );
1✔
178
        }
179

180
        if ( ! ranges.isEmpty() ) {
1✔
181
            JsonArrayBuilder rangesBld = Json.createArrayBuilder();
1✔
182
            ranges.forEach( r -> rangesBld.add( Json.createArrayBuilder().add(r.get(0)).add(r.get(1))) );
1✔
183
            bld.add("ranges", rangesBld );
1✔
184
        }
185

186
        return bld;
1✔
187
    }
188

189
    public static JsonObjectBuilder json(ShibGroup grp) {
190
        return jsonObjectBuilder()
×
191
                .add("name", grp.getName())
×
192
                .add("attribute", grp.getAttribute())
×
193
                .add("pattern", grp.getPattern())
×
194
                .add("id", grp.getId());
×
195
    }
196

197
    public static JsonObjectBuilder json(MailDomainGroup grp) {
198
        JsonObjectBuilder bld = jsonObjectBuilder()
1✔
199
            .add("alias", grp.getPersistedGroupAlias() )
1✔
200
            .add("id", grp.getId() )
1✔
201
            .add("name", grp.getDisplayName() )
1✔
202
            .add("description", grp.getDescription() )
1✔
203
            .add("domains", asJsonArray(grp.getEmailDomainsAsList()) )
1✔
204
            .add("regex", grp.isRegEx());
1✔
205
        return bld;
1✔
206
    }
207

208
    public static JsonArrayBuilder rolesToJson(List<DataverseRole> role) {
209
        JsonArrayBuilder bld = Json.createArrayBuilder();
×
210
        for (DataverseRole r : role) {
×
211
            bld.add(JsonPrinter.json(r));
×
212
        }
×
213
        return bld;
×
214
    }
215

216
    public static <E extends Enum> JsonArrayBuilder enumsToJson(Collection<E> collection) {
217
        JsonArrayBuilder arr = Json.createArrayBuilder();
1✔
218
        for (E entry : collection) {
1✔
219
            arr.add(entry.name());
1✔
220
        }
1✔
221
        return arr;
1✔
222
    }
223

224
    public static JsonObjectBuilder json(DataverseRole role) {
225
        JsonObjectBuilder bld = jsonObjectBuilder()
×
226
                .add("alias", role.getAlias())
×
227
                .add("name", role.getName())
×
228
                .add("permissions", JsonPrinter.json(role.permissions()))
×
229
                .add("description", role.getDescription());
×
230
        if (role.getId() != null) {
×
231
            bld.add("id", role.getId());
×
232
        }
233
        if (role.getOwner() != null && role.getOwner().getId() != null) {
×
234
            bld.add("ownerId", role.getOwner().getId());
×
235
        }
236

237
        return bld;
×
238
    }
239

240
    public static JsonObjectBuilder json(Workflow wf){
241
        JsonObjectBuilder bld = jsonObjectBuilder();
×
242
        bld.add("name", wf.getName());
×
243
        if ( wf.getId() != null ) {
×
244
            bld.add("id", wf.getId());
×
245
        }
246

247
        if ( wf.getSteps()!=null && !wf.getSteps().isEmpty()) {
×
248
            JsonArrayBuilder arr = Json.createArrayBuilder();
×
249
            for ( WorkflowStepData stp : wf.getSteps() ) {
×
250
                arr.add( jsonObjectBuilder().add("stepType", stp.getStepType())
×
251
                                   .add("provider", stp.getProviderId())
×
252
                                   .add("parameters", mapToObject(stp.getStepParameters()))
×
253
                                   .add("requiredSettings", mapToObject(stp.getStepSettings())) );
×
254
            }
×
255
            bld.add("steps", arr );
×
256
        }
257

258
        return bld;
×
259
    }
260

261
    public static JsonObjectBuilder json(Dataverse dv) {
262
        return json(dv, false, false);
1✔
263
    }
264

265
    //TODO: Once we upgrade to Java EE 8 we can remove objects from the builder, and this email removal can be done in a better place.
266
    public static JsonObjectBuilder json(Dataverse dv, Boolean hideEmail, Boolean returnOwners) {
267
        JsonObjectBuilder bld = jsonObjectBuilder()
1✔
268
                .add("id", dv.getId())
1✔
269
                .add("alias", dv.getAlias())
1✔
270
                .add("name", dv.getName())
1✔
271
                .add("affiliation", dv.getAffiliation());
1✔
272
        if(!hideEmail) {
1✔
273
            bld.add("dataverseContacts", JsonPrinter.json(dv.getDataverseContacts()));
1✔
274
        }
275
        if (returnOwners){
1✔
276
            bld.add("isPartOf", getOwnersFromDvObject(dv));
×
277
        }
278
        bld.add("permissionRoot", dv.isPermissionRoot())
1✔
279
                .add("description", dv.getDescription())
1✔
280
                .add("dataverseType", dv.getDataverseType().name())
1✔
281
                .add("isMetadataBlockRoot", dv.isMetadataBlockRoot())
1✔
282
                .add("isFacetRoot", dv.isFacetRoot());
1✔
283
        if (dv.getOwner() != null) {
1✔
284
            bld.add("ownerId", dv.getOwner().getId());
×
285
        }
286
        if (dv.getCreateDate() != null) {
1✔
287
            bld.add("creationDate", Util.getDateTimeFormat().format(dv.getCreateDate()));
×
288
        }
289
        if (dv.getDataverseTheme() != null) {
1✔
290
            bld.add("theme", JsonPrinter.json(dv.getDataverseTheme()));
×
291
        }
292
        if(dv.getStorageDriverId() != null) {
1✔
293
                bld.add("storageDriverLabel", DataAccess.getStorageDriverLabelFor(dv.getStorageDriverId()));
1✔
294
        }
295
        if (dv.getFilePIDsEnabled() != null) {
1✔
296
            bld.add("filePIDsEnabled", dv.getFilePIDsEnabled());
×
297
        }
298
        bld.add("effectiveRequiresFilesToPublishDataset", dv.getEffectiveRequiresFilesToPublishDataset());
1✔
299
        bld.add("isReleased", dv.isReleased());
1✔
300

301
        List<DataverseFieldTypeInputLevel> inputLevels = dv.getDataverseFieldTypeInputLevels();
1✔
302
        if(!inputLevels.isEmpty()) {
1✔
303
            bld.add("inputLevels", JsonPrinter.jsonDataverseFieldTypeInputLevels(inputLevels));
×
304
        }
305

306
        return bld;
1✔
307
    }
308

309
    public static JsonArrayBuilder json(List<DataverseContact> dataverseContacts) {
310
        JsonArrayBuilder jsonArrayOfContacts = Json.createArrayBuilder();
1✔
311
        for (DataverseContact dataverseContact : dataverseContacts) {
1✔
312
            NullSafeJsonBuilder contactJsonObject = NullSafeJsonBuilder.jsonObjectBuilder();
1✔
313
            contactJsonObject.add("displayOrder", dataverseContact.getDisplayOrder());
1✔
314
            contactJsonObject.add("contactEmail", dataverseContact.getContactEmail());
1✔
315
            jsonArrayOfContacts.add(contactJsonObject);
1✔
316
        }
1✔
317
        return jsonArrayOfContacts;
1✔
318
    }
319

320
    public static JsonObjectBuilder getOwnersFromDvObject(DvObject dvObject){
321
        return getOwnersFromDvObject(dvObject, null);
×
322
    }
323

324
    public static JsonObjectBuilder getOwnersFromDvObject(DvObject dvObject, DatasetVersion dsv) {
325
        List <DvObject> ownerList = new ArrayList();
×
326
        dvObject = dvObject.getOwner(); // We're going to ignore the object itself
×
327
        //Get "root" to top of list
328
        while (dvObject != null) {
×
329
            ownerList.add(0, dvObject);
×
330
            dvObject = dvObject.getOwner();
×
331
        }
332
        //then work "inside out"
333
        JsonObjectBuilder saved = null;
×
334
        for (DvObject dvo : ownerList) {
×
335
            saved = addEmbeddedOwnerObject(dvo, saved, dsv);
×
336
        }
×
337
        return saved;
×
338
    }
339

340
    private static JsonObjectBuilder addEmbeddedOwnerObject(DvObject dvo, JsonObjectBuilder isPartOf, DatasetVersion dsv ) {
341
        JsonObjectBuilder ownerObject = jsonObjectBuilder();
×
342

343
        if (dvo.isInstanceofDataverse()) {
×
344
            ownerObject.add("type", "DATAVERSE");
×
345
            Dataverse in = (Dataverse) dvo;
×
346
            ownerObject.add("identifier", in.getAlias());
×
347
            ownerObject.add("isReleased", in.isReleased());
×
348
        }
349

350
        if (dvo.isInstanceofDataset()) {
×
351
            ownerObject.add("type", "DATASET");
×
352
            if (dvo.getGlobalId() != null) {
×
353
                ownerObject.add("persistentIdentifier", dvo.getGlobalId().asString());
×
354
            }
355
            ownerObject.add("identifier", dvo.getId());
×
356
            String versionString = dsv == null ? "" : dsv.getFriendlyVersionNumber();
×
357
            if (!versionString.isEmpty()){
×
358
               ownerObject.add("version", versionString);
×
359
            }
360
        }
361

362
        ownerObject.add("displayName", dvo.getDisplayName());
×
363

364
        if (isPartOf != null) {
×
365
            ownerObject.add("isPartOf", isPartOf);
×
366
        }
367

368
        return ownerObject;
×
369
    }
370

371
    public static JsonObjectBuilder json( DataverseTheme theme ) {
372
        final NullSafeJsonBuilder baseObject = jsonObjectBuilder()
×
373
                .add("id", theme.getId() )
×
374
                .add("logo", theme.getLogo())
×
375
                .add("tagline", theme.getTagline())
×
376
                .add("linkUrl", theme.getLinkUrl())
×
377
                .add("linkColor", theme.getLinkColor())
×
378
                .add("textColor", theme.getTextColor())
×
379
                .add("backgroundColor", theme.getBackgroundColor());
×
380
        if ( theme.getLogoAlignment() != null ) {
×
381
            baseObject.add("logoBackgroundColor", theme.getLogoBackgroundColor());
×
382
        }
383
        return baseObject;
×
384
    }
385

386
    public static JsonObjectBuilder json(BuiltinUser user) {
387
        return (user == null)
×
388
                ? null
×
389
                : jsonObjectBuilder()
×
390
                .add("id", user.getId())
×
391
                .add("userName", user.getUserName());
×
392
    }
393

394
    public static JsonObjectBuilder json(Dataset ds){
395
       return json(ds, false);
×
396
    }
397

398
    public static JsonObjectBuilder json(Dataset ds, Boolean returnOwners) {
399
        JsonObjectBuilder bld = jsonObjectBuilder()
×
400
                .add("id", ds.getId())
×
401
                .add("identifier", ds.getIdentifier())
×
402
                .add("persistentUrl", ds.getPersistentURL())
×
403
                .add("protocol", ds.getProtocol())
×
404
                .add("authority", ds.getAuthority())
×
NEW
405
                .add("separator", ds.getSeparator())
×
406
                .add("publisher", BrandingUtil.getInstallationBrandName())
×
407
                .add("publicationDate", ds.getPublicationDateFormattedYYYYMMDD())
×
408
                .add("storageIdentifier", ds.getStorageIdentifier());
×
409
        if (DvObjectContainer.isMetadataLanguageSet(ds.getMetadataLanguage())) {
×
410
            bld.add("metadataLanguage", ds.getMetadataLanguage());
×
411
        }
412
        if (returnOwners){
×
413
            bld.add("isPartOf", getOwnersFromDvObject(ds));
×
414
        }
415
        bld.add("datasetType", ds.getDatasetType().getName());
×
416
        return bld;
×
417
    }
418

419
    public static JsonObjectBuilder json(FileDetailsHolder ds) {
420
        return Json.createObjectBuilder().add(ds.getStorageID() ,
×
421
                Json.createObjectBuilder()
×
422
                .add("id", ds.getStorageID() )
×
423
                .add("hash", ds.getHash())
×
424
                .add("mime",ds.getMime()));
×
425
    }
426

427
    public static JsonObjectBuilder json(DatasetVersion dsv, boolean includeFiles) {
428
        return json(dsv, null, includeFiles, false,true);
×
429
    }
430
    public static JsonObjectBuilder json(DatasetVersion dsv, boolean includeFiles, boolean includeMetadataBlocks) {
431
        return json(dsv, null, includeFiles, false, includeMetadataBlocks);
×
432
    }
433
    public static JsonObjectBuilder json(DatasetVersion dsv, List<String> anonymizedFieldTypeNamesList,
434
                                         boolean includeFiles, boolean returnOwners) {
435
        return  json( dsv,  anonymizedFieldTypeNamesList, includeFiles,  returnOwners,true);
×
436
    }
437
    public static JsonObjectBuilder json(DatasetVersion dsv, List<String> anonymizedFieldTypeNamesList,
438
        boolean includeFiles, boolean returnOwners, boolean includeMetadataBlocks) {
439
        Dataset dataset = dsv.getDataset();
×
440
        JsonObjectBuilder bld = jsonObjectBuilder()
×
441
                .add("id", dsv.getId()).add("datasetId", dataset.getId())
×
442
                .add("datasetPersistentId", dataset.getGlobalId().asString())
×
443
                .add("storageIdentifier", dataset.getStorageIdentifier())
×
444
                .add("versionNumber", dsv.getVersionNumber())
×
445
                .add("versionMinorNumber", dsv.getMinorVersionNumber())
×
446
                .add("versionState", dsv.getVersionState().name())
×
447
                .add("latestVersionPublishingState", dataset.getLatestVersion().getVersionState().name())
×
448
                .add("versionNote", dsv.getVersionNote())
×
449
                .add("archiveNote", dsv.getArchiveNote())
×
450
                .add("deaccessionLink", dsv.getDeaccessionLink())
×
451
                .add("distributionDate", dsv.getDistributionDate())
×
452
                .add("productionDate", dsv.getProductionDate())
×
453
                .add("UNF", dsv.getUNF()).add("archiveTime", format(dsv.getArchiveTime()))
×
454
                .add("lastUpdateTime", format(dsv.getLastUpdateTime()))
×
455
                .add("releaseTime", format(dsv.getReleaseTime()))
×
456
                .add("createTime", format(dsv.getCreateTime()))
×
457
                .add("alternativePersistentId", dataset.getAlternativePersistentIdentifier())
×
458
                .add("publicationDate", dataset.getPublicationDateFormattedYYYYMMDD())
×
459
                .add("citationDate", dataset.getCitationDateFormattedYYYYMMDD());
×
460

461
        License license = DatasetUtil.getLicense(dsv);
×
462
        if (license != null) {
×
463
            bld.add("license", jsonLicense(dsv));
×
464
        } else {
465
            // Custom terms
466
            bld.add("termsOfUse", dsv.getTermsOfUseAndAccess().getTermsOfUse())
×
467
                    .add("confidentialityDeclaration", dsv.getTermsOfUseAndAccess().getConfidentialityDeclaration())
×
468
                    .add("specialPermissions", dsv.getTermsOfUseAndAccess().getSpecialPermissions())
×
469
                    .add("restrictions", dsv.getTermsOfUseAndAccess().getRestrictions())
×
470
                    .add("citationRequirements", dsv.getTermsOfUseAndAccess().getCitationRequirements())
×
471
                    .add("depositorRequirements", dsv.getTermsOfUseAndAccess().getDepositorRequirements())
×
472
                    .add("conditions", dsv.getTermsOfUseAndAccess().getConditions())
×
473
                    .add("disclaimer", dsv.getTermsOfUseAndAccess().getDisclaimer());
×
474
        }
475
        bld.add("termsOfAccess", dsv.getTermsOfUseAndAccess().getTermsOfAccess())
×
476
                .add("dataAccessPlace", dsv.getTermsOfUseAndAccess().getDataAccessPlace())
×
477
                .add("originalArchive", dsv.getTermsOfUseAndAccess().getOriginalArchive())
×
478
                .add("availabilityStatus", dsv.getTermsOfUseAndAccess().getAvailabilityStatus())
×
479
                .add("contactForAccess", dsv.getTermsOfUseAndAccess().getContactForAccess())
×
480
                .add("sizeOfCollection", dsv.getTermsOfUseAndAccess().getSizeOfCollection())
×
481
                .add("studyCompletion", dsv.getTermsOfUseAndAccess().getStudyCompletion())
×
482
                .add("fileAccessRequest", dsv.getTermsOfUseAndAccess().isFileAccessRequest());
×
483
        if(includeMetadataBlocks) {
×
484
            bld.add("metadataBlocks", (anonymizedFieldTypeNamesList != null) ?
×
485
                    jsonByBlocks(dsv.getDatasetFields(), anonymizedFieldTypeNamesList)
×
486
                    : jsonByBlocks(dsv.getDatasetFields())
×
487
            );
488
        }
489
        if(returnOwners){
×
490
            bld.add("isPartOf", getOwnersFromDvObject(dataset));
×
491
        }
492
        if (includeFiles) {
×
493
            bld.add("files", jsonFileMetadatas(dsv.getFileMetadatas()));
×
494
        }
495

496
        return bld;
×
497
    }
498

499
    public static JsonObjectBuilder jsonDataFileList(List<DataFile> dataFiles){
500

501
        if (dataFiles==null){
×
502
            throw new NullPointerException("dataFiles cannot be null");
×
503
        }
504

505
        JsonObjectBuilder bld = jsonObjectBuilder();
×
506

507

508
        List<FileMetadata> dataFileList = dataFiles.stream()
×
509
                                    .map(x -> x.getFileMetadata())
×
510
                                    .collect(Collectors.toList());
×
511

512

513
        bld.add("files", jsonFileMetadatas(dataFileList));
×
514

515
        return bld;
×
516
    }
517

518
    /**
519
     * Export formats such as DDI require the citation to be included. See
520
     * https://github.com/IQSS/dataverse/issues/2579 for more on DDI export.
521
     *
522
     * @todo Instead of having this separate method, should "citation" be added
523
     * to the regular `json` method for DatasetVersion? Will anything break?
524
     * Unit tests for that method could not be found.
525
     */
526
    public static JsonObjectBuilder jsonWithCitation(DatasetVersion dsv, boolean includeFiles) {
527
        JsonObjectBuilder dsvWithCitation = JsonPrinter.json(dsv, includeFiles);
×
528
        dsvWithCitation.add("citation", dsv.getCitation());
×
529
        return dsvWithCitation;
×
530
    }
531

532
    /**
533
     * Export formats such as DDI require the persistent identifier components
534
     * such as "protocol", "authority" and "identifier" to be included so we
535
     * create a JSON object we can convert to a DatasetDTO which can include a
536
     * DatasetVersionDTO, which has all the metadata fields we need to export.
537
     * See https://github.com/IQSS/dataverse/issues/2579 for more on DDI export.
538
     *
539
     * @todo Instead of having this separate method, should "datasetVersion" be
540
     * added to the regular `json` method for Dataset? Will anything break? Unit
541
     * tests for that method could not be found. If we keep this method as-is
542
     * should the method be renamed?
543
     */
544
    public static JsonObjectBuilder jsonAsDatasetDto(DatasetVersion dsv) {
545
        JsonObjectBuilder datasetDtoAsJson = JsonPrinter.json(dsv.getDataset());
×
546
        datasetDtoAsJson.add("datasetVersion", jsonWithCitation(dsv, true));
×
547
        return datasetDtoAsJson;
×
548
    }
549

550
    public static JsonArrayBuilder jsonFileMetadatas(Collection<FileMetadata> fmds) {
551
        JsonArrayBuilder filesArr = Json.createArrayBuilder();
×
552
        for (FileMetadata fmd : fmds) {
×
553
            filesArr.add(JsonPrinter.json(fmd));
×
554
        }
×
555

556
        return filesArr;
×
557
    }
558

559
    public static JsonObjectBuilder json(DatasetDistributor dist) {
560
        return jsonObjectBuilder()
×
561
                .add("displayOrder", dist.getDisplayOrder())
×
562
                .add("version", dist.getVersion())
×
563
                .add("abbreviation", JsonPrinter.json(dist.getAbbreviation()))
×
564
                .add("affiliation", JsonPrinter.json(dist.getAffiliation()))
×
565
                .add("logo", JsonPrinter.json(dist.getLogo()))
×
566
                .add("name", JsonPrinter.json(dist.getName()))
×
567
                .add("url", JsonPrinter.json(dist.getUrl()));
×
568
    }
569

570
    public static JsonObjectBuilder jsonByBlocks(List<DatasetField> fields) {
571
        return jsonByBlocks(fields, null);
1✔
572
    }
573

574
    public static JsonObjectBuilder jsonByBlocks(List<DatasetField> fields, List<String> anonymizedFieldTypeNamesList) {
575
        JsonObjectBuilder blocksBld = jsonObjectBuilder();
1✔
576

577
        for (Map.Entry<MetadataBlock, List<DatasetField>> blockAndFields : DatasetField.groupByBlock(fields).entrySet()) {
1✔
578
            MetadataBlock block = blockAndFields.getKey();
1✔
579
            blocksBld.add(block.getName(), JsonPrinter.json(block, blockAndFields.getValue(), anonymizedFieldTypeNamesList));
1✔
580
        }
1✔
581
        return blocksBld;
1✔
582
    }
583

584
    /**
585
     * Create a JSON object for the block and its fields. The fields are assumed
586
     * to belong to the block - there's no checking of that in the method.
587
     *
588
     * @param block
589
     * @param fields
590
     * @return JSON Object builder with the block and fields information.
591
     */
592
    public static JsonObjectBuilder json(MetadataBlock block, List<DatasetField> fields) {
593
        return json(block, fields, null);
1✔
594
    }
595

596
    public static JsonObjectBuilder json(MetadataBlock block, List<DatasetField> fields, List<String> anonymizedFieldTypeNamesList) {
597
        JsonObjectBuilder blockBld = jsonObjectBuilder();
1✔
598

599
        blockBld.add("displayName", block.getDisplayName());
1✔
600
        blockBld.add("name", block.getName());
1✔
601

602
        final JsonArrayBuilder fieldsArray = Json.createArrayBuilder();
1✔
603
        Map<Long, JsonObject> cvocMap = (datasetFieldService==null) ? new HashMap<Long, JsonObject>() :datasetFieldService.getCVocConf(true);
1✔
604
        DatasetFieldWalker.walk(fields, settingsService, cvocMap, new DatasetFieldsToJson(fieldsArray, anonymizedFieldTypeNamesList));
1✔
605

606
        blockBld.add("fields", fieldsArray);
1✔
607
        return blockBld;
1✔
608
    }
609

610
    public static JsonArrayBuilder json(List<MetadataBlock> metadataBlocks, boolean returnDatasetFieldTypes, boolean printOnlyDisplayedOnCreateDatasetFieldTypes) {
611
        return json(metadataBlocks, returnDatasetFieldTypes, printOnlyDisplayedOnCreateDatasetFieldTypes, null);
×
612
    }
613

614
    public static JsonArrayBuilder json(List<MetadataBlock> metadataBlocks, boolean returnDatasetFieldTypes, boolean printOnlyDisplayedOnCreateDatasetFieldTypes, Dataverse ownerDataverse) {
615
        JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
×
616
        for (MetadataBlock metadataBlock : metadataBlocks) {
×
617
            arrayBuilder.add(returnDatasetFieldTypes ? json(metadataBlock, printOnlyDisplayedOnCreateDatasetFieldTypes, ownerDataverse) : brief.json(metadataBlock));
×
618
        }
×
619
        return arrayBuilder;
×
620
    }
621

622
    public static String typeClassString(DatasetFieldType typ) {
623
        if (typ.isControlledVocabulary()) {
1✔
624
            return "controlledVocabulary";
1✔
625
        }
626
        if (typ.isCompound()) {
1✔
627
            return "compound";
1✔
628
        }
629
        return "primitive";
1✔
630
    }
631

632
    public static JsonObject json(DatasetField dfv) {
633
        if (dfv.isEmpty()) {
1✔
634
            return null;
×
635
        } else {
636
            JsonArrayBuilder fieldArray = Json.createArrayBuilder();
1✔
637
            Map<Long, JsonObject> cvocMap = (datasetFieldService==null) ? new HashMap<Long, JsonObject>() :datasetFieldService.getCVocConf(true);
1✔
638
            DatasetFieldWalker.walk(dfv, new DatasetFieldsToJson(fieldArray), cvocMap);
1✔
639
            JsonArray out = fieldArray.build();
1✔
640
            return out.getJsonObject(0);
1✔
641
        }
642
    }
643

644
    public static JsonObjectBuilder json(MetadataBlock metadataBlock) {
645
        return json(metadataBlock, false, null);
1✔
646
    }
647

648
    public static JsonObjectBuilder json(MetadataBlock metadataBlock, boolean printOnlyDisplayedOnCreateDatasetFieldTypes, Dataverse ownerDataverse) {
649
        JsonObjectBuilder jsonObjectBuilder = jsonObjectBuilder()
1✔
650
                .add("id", metadataBlock.getId())
1✔
651
                .add("name", metadataBlock.getName())
1✔
652
                .add("displayName", metadataBlock.getDisplayName())
1✔
653
                .add("displayOnCreate", metadataBlock.isDisplayOnCreate());
1✔
654

655
        List<DatasetFieldType> datasetFieldTypesList;
656

657
        if (ownerDataverse != null) {
1✔
658
            datasetFieldTypesList = datasetFieldService.findAllInMetadataBlockAndDataverse(
×
659
                    metadataBlock, ownerDataverse, printOnlyDisplayedOnCreateDatasetFieldTypes);
660
        } else {
661
            datasetFieldTypesList = printOnlyDisplayedOnCreateDatasetFieldTypes
1✔
662
                    ? datasetFieldService.findAllDisplayedOnCreateInMetadataBlock(metadataBlock)
×
663
                    : metadataBlock.getDatasetFieldTypes();
1✔
664
        }
665

666
        Set<DatasetFieldType> datasetFieldTypes = filterOutDuplicateDatasetFieldTypes(datasetFieldTypesList);
1✔
667

668
        JsonObjectBuilder fieldsBuilder = Json.createObjectBuilder();
1✔
669
        
670
        Predicate<DatasetFieldType> isNoChild = element -> element.isChild() == false;
1✔
671
        List<DatasetFieldType> childLessList = metadataBlock.getDatasetFieldTypes().stream().filter(isNoChild).toList();
1✔
672
        Set<DatasetFieldType> datasetFieldTypesNoChildSorted = new TreeSet<>(childLessList);
1✔
673
        
674
        for (DatasetFieldType datasetFieldType : datasetFieldTypesNoChildSorted) {
1✔
675
            
676
            Long datasetFieldTypeId = datasetFieldType.getId();
1✔
677
            boolean requiredAsInputLevelInOwnerDataverse = ownerDataverse != null && ownerDataverse.isDatasetFieldTypeRequiredAsInputLevel(datasetFieldTypeId);
1✔
678
            boolean includedAsInputLevelInOwnerDataverse = ownerDataverse != null && ownerDataverse.isDatasetFieldTypeIncludedAsInputLevel(datasetFieldTypeId);
1✔
679
            boolean isNotInputLevelInOwnerDataverse = ownerDataverse != null && !ownerDataverse.isDatasetFieldTypeInInputLevels(datasetFieldTypeId);
1✔
680

681
            DatasetFieldType parentDatasetFieldType = datasetFieldType.getParentDatasetFieldType();
1✔
682
            boolean isRequired = parentDatasetFieldType == null ? datasetFieldType.isRequired() : parentDatasetFieldType.isRequired();
1✔
683

684
            boolean displayCondition = printOnlyDisplayedOnCreateDatasetFieldTypes
1✔
685
                    ? (datasetFieldType.isDisplayOnCreate() || isRequired || requiredAsInputLevelInOwnerDataverse)
×
686
                    : ownerDataverse == null || includedAsInputLevelInOwnerDataverse || isNotInputLevelInOwnerDataverse;
1✔
687

688
            if (displayCondition) {
1✔
689
                fieldsBuilder.add(datasetFieldType.getName(), json(datasetFieldType, ownerDataverse));
1✔
690
            }
691
        }
1✔
692
        
693
        jsonObjectBuilder.add("fields", fieldsBuilder);
1✔
694
        return jsonObjectBuilder;
1✔
695
    }
696

697
    // This will remove datasetFieldTypes that are in the list but also a child of another datasetFieldType in the list
698
    // Prevents duplicate datasetFieldType information from being returned twice
699
    // See: https://github.com/IQSS/dataverse/issues/10472
700
    private static Set<DatasetFieldType> filterOutDuplicateDatasetFieldTypes(List<DatasetFieldType> datasetFieldTypesList) {
701
        // making a copy of the list as to not damage the original when we remove items
702
        List<DatasetFieldType> datasetFieldTypes = new ArrayList<>(datasetFieldTypesList);
1✔
703
        // exclude/remove datasetFieldTypes if datasetFieldType exists as a child of another datasetFieldType
704
        datasetFieldTypesList.forEach(dsft -> dsft.getChildDatasetFieldTypes().forEach(c -> datasetFieldTypes.remove(c)));
1✔
705
        return new TreeSet<>(datasetFieldTypes);
1✔
706
    }
707

708
    public static JsonArrayBuilder jsonDatasetFieldTypes(List<DatasetFieldType> fields) {
709
        JsonArrayBuilder fieldsJson = Json.createArrayBuilder();
×
710
        for (DatasetFieldType field : fields) {
×
711
            fieldsJson.add(JsonPrinter.json(field));
×
712
        }
×
713
        return fieldsJson;
×
714
    }
715

716
    public static JsonObjectBuilder json(DatasetFieldType fld) {
717
        return json(fld, null);
×
718
    }
719

720
    public static JsonObjectBuilder json(DatasetFieldType fld, Dataverse ownerDataverse) {
721
        JsonObjectBuilder fieldsBld = jsonObjectBuilder();
1✔
722
        fieldsBld.add("name", fld.getName());
1✔
723
        fieldsBld.add("displayName", fld.getDisplayName());
1✔
724
        fieldsBld.add("displayOnCreate", fld.isDisplayOnCreate());
1✔
725
        fieldsBld.add("title", fld.getTitle());
1✔
726
        fieldsBld.add("type", fld.getFieldType().toString());
1✔
727
        fieldsBld.add("typeClass", typeClassString(fld));
1✔
728
        fieldsBld.add("watermark", fld.getWatermark());
1✔
729
        fieldsBld.add("description", fld.getDescription());
1✔
730
        fieldsBld.add("multiple", fld.isAllowMultiples());
1✔
731
        fieldsBld.add("isControlledVocabulary", fld.isControlledVocabulary());
1✔
732
        fieldsBld.add("displayFormat", fld.getDisplayFormat());
1✔
733
        fieldsBld.add("displayOrder", fld.getDisplayOrder());
1✔
734

735
        boolean requiredInOwnerDataverse = ownerDataverse != null && ownerDataverse.isDatasetFieldTypeRequiredAsInputLevel(fld.getId());
1✔
736
        fieldsBld.add("isRequired", requiredInOwnerDataverse || fld.isRequired());
1✔
737

738
        if (fld.isControlledVocabulary()) {
1✔
739
            // If the field has a controlled vocabulary,
740
            // add all values to the resulting JSON
741
            JsonArrayBuilder jab = Json.createArrayBuilder();
×
742
            for (ControlledVocabularyValue cvv : fld.getControlledVocabularyValues()) {
×
743
                jab.add(cvv.getStrValue());
×
744
            }
×
745
            fieldsBld.add("controlledVocabularyValues", jab);
×
746
        }
747

748
        if (!fld.getChildDatasetFieldTypes().isEmpty()) {
1✔
749
            JsonObjectBuilder subFieldsBld = jsonObjectBuilder();
1✔
750
            for (DatasetFieldType subFld : fld.getChildDatasetFieldTypes()) {
1✔
751
                subFieldsBld.add(subFld.getName(), JsonPrinter.json(subFld, ownerDataverse));
1✔
752
            }
1✔
753
            fieldsBld.add("childFields", subFieldsBld);
1✔
754
        }
755

756
        return fieldsBld;
1✔
757
    }
758

759
    public static JsonObjectBuilder json(FileMetadata fmd){
760
        return json(fmd, false, false);
1✔
761
    }
762

763
    public static JsonObjectBuilder json(FileMetadata fmd, boolean returnOwners, boolean printDatasetVersion) {
764
        NullSafeJsonBuilder builder = jsonObjectBuilder();
1✔
765

766
                // deprecated: .add("category", fmd.getCategory())
767
                // TODO: uh, figure out what to do here... it's deprecated
768
                // in a sense that there's no longer the category field in the
769
                // fileMetadata object; but there are now multiple, oneToMany file
770
                // categories - and we probably need to export them too!) -- L.A. 4.5
771
                // DONE: catgegories by name
772
                builder.add("description", fmd.getDescription())
1✔
773
                .add("label", fmd.getLabel()) // "label" is the filename
1✔
774
                .add("restricted", fmd.isRestricted())
1✔
775
                .add("directoryLabel", fmd.getDirectoryLabel())
1✔
776
                .add("version", fmd.getVersion())
1✔
777
                .add("datasetVersionId", fmd.getDatasetVersion().getId())
1✔
778
                .add("categories", getFileCategories(fmd))
1✔
779
                .add("dataFile", JsonPrinter.json(fmd.getDataFile(), fmd, false, returnOwners));
1✔
780

781
        if (printDatasetVersion) {
1✔
782
            builder.add("datasetVersion", json(fmd.getDatasetVersion(), false));
×
783
        }
784

785
        return builder;
1✔
786
    }
787

788
    public static JsonObjectBuilder json(AuxiliaryFile auxFile) {
789
        return jsonObjectBuilder()
×
790
               .add("formatTag", auxFile.getFormatTag())
×
791
                .add("formatVersion", auxFile.getFormatVersion()) // "label" is the filename
×
792
                .add("origin", auxFile.getOrigin())
×
793
                .add("isPublic", auxFile.getIsPublic())
×
794
                .add("type", auxFile.getType())
×
795
                .add("contentType", auxFile.getContentType())
×
796
                .add("fileSize", auxFile.getFileSize())
×
797
                .add("checksum", auxFile.getChecksum())
×
798
                .add("dataFile", JsonPrinter.json(auxFile.getDataFile()));
×
799
    }
800

801
    public static JsonObjectBuilder json(DataFile df) {
802
        return JsonPrinter.json(df, null, false);
×
803
    }
804

805
    public static JsonObjectBuilder json(DataFile df, FileMetadata fileMetadata, boolean forExportDataProvider){
806
        return json(df, fileMetadata, forExportDataProvider, false);
×
807
    }
808

809
    public static JsonObjectBuilder json(DataFile df, FileMetadata fileMetadata, boolean forExportDataProvider, boolean returnOwners) {
810
        // File names are no longer stored in the DataFile entity; 
811
        // (they are instead in the FileMetadata (as "labels") - this way 
812
        // the filename can change between versions... 
813
        // It does appear that for some historical purpose we still need the
814
        // filename in the file DTO (?)... We rely on it to be there for the 
815
        // DDI export, for example. So we need to make sure this is is the 
816
        // *correct* file name - i.e., that it comes from the right version. 
817
        // (TODO...? L.A. 4.5, Aug 7 2016)
818
        String fileName = null;
1✔
819

820
        if (fileMetadata == null){
1✔
821
            // Note that this may not necessarily grab the file metadata from the 
822
            // version *you want*! (L.A.)
823
            fileMetadata = df.getFileMetadata();
×
824
        }
825

826
        fileName = fileMetadata.getLabel();
1✔
827
        GlobalId filePid = df.getGlobalId();
1✔
828
        String pidURL = (filePid!=null)? filePid.asURL(): null;
1✔
829
        //For backward compatibility - prior to #8674, asString() returned "" for the value when no PID exists.
830
        String pidString = (filePid!=null)? filePid.asString(): "";
1✔
831

832
        JsonObjectBuilder embargo = df.getEmbargo() != null ? JsonPrinter.json(df.getEmbargo()) : null;
1✔
833
        JsonObjectBuilder retention = df.getRetention() != null ? JsonPrinter.json(df.getRetention()) : null;
1✔
834

835
        NullSafeJsonBuilder builder = jsonObjectBuilder()
1✔
836
                .add("id", df.getId())
1✔
837
                .add("persistentId", pidString)
1✔
838
                .add("pidURL", pidURL)
1✔
839
                .add("filename", fileName)
1✔
840
                .add("contentType", df.getContentType())
1✔
841
                .add("friendlyType", df.getFriendlyType())
1✔
842
                .add("filesize", df.getFilesize())
1✔
843
                .add("description", fileMetadata.getDescription())
1✔
844
                .add("categories", getFileCategories(fileMetadata))
1✔
845
                .add("embargo", embargo)
1✔
846
                .add("retention", retention)
1✔
847
                //.add("released", df.isReleased())
848
                .add("storageIdentifier", df.getStorageIdentifier())
1✔
849
                .add("originalFileFormat", df.getOriginalFileFormat())
1✔
850
                .add("originalFormatLabel", df.getOriginalFormatLabel())
1✔
851
                .add ("originalFileSize", df.getOriginalFileSize())
1✔
852
                .add("originalFileName", df.getOriginalFileName())
1✔
853
                .add("UNF", df.getUnf())
1✔
854
                //---------------------------------------------
855
                // For file replace: rootDataFileId, previousDataFileId
856
                //---------------------------------------------
857
                .add("rootDataFileId", df.getRootDataFileId())
1✔
858
                .add("previousDataFileId", df.getPreviousDataFileId())
1✔
859
                //---------------------------------------------
860
                // Checksum
861
                // * @todo Should we deprecate "md5" now that it's under
862
                // * "checksum" (which may also be a SHA-1 rather than an MD5)? - YES!
863
                //---------------------------------------------
864
                .add("md5", getMd5IfItExists(df.getChecksumType(), df.getChecksumValue()))
1✔
865
                .add("checksum", getChecksumTypeAndValue(df.getChecksumType(), df.getChecksumValue()))
1✔
866
                .add("tabularData", df.isTabularData())
1✔
867
                .add("tabularTags", getTabularFileTags(df))
1✔
868
                .add("creationDate", df.getCreateDateFormattedYYYYMMDD())
1✔
869
                .add("publicationDate",  df.getPublicationDateFormattedYYYYMMDD());
1✔
870
        Dataset dfOwner = df.getOwner();
1✔
871
        if (dfOwner != null) {
1✔
872
            builder.add("fileAccessRequest", dfOwner.isFileAccessRequest());
×
873
        }
874
        /*
875
         * The restricted state was not included prior to #9175 so to avoid backward
876
         * incompatability, it is now only added when generating json for the
877
         * InternalExportDataProvider fileDetails.
878
         */
879
        if (forExportDataProvider) {
1✔
880
            builder.add("restricted", df.isRestricted())
×
881
            .add("fileMetadataId", fileMetadata.getId())
×
882
            .add("dataTables", df.getDataTables().isEmpty() ? null : JsonPrinter.jsonDT(df.getDataTables()))
×
883
            .add("varGroups", fileMetadata.getVarGroups().isEmpty()
×
884
                    ? JsonPrinter.jsonVarGroup(fileMetadata.getVarGroups())
×
885
                    : null);
×
886
        }
887
        if (returnOwners){
1✔
888
            builder.add("isPartOf", getOwnersFromDvObject(df, fileMetadata.getDatasetVersion()));
×
889
        }
890
        return builder;
1✔
891
    }
892

893
    //Started from https://github.com/RENCI-NRIG/dataverse/, i.e. https://github.com/RENCI-NRIG/dataverse/commit/2b5a1225b42cf1caba85e18abfeb952171c6754a
894
    public static JsonArrayBuilder jsonDT(List<DataTable> ldt) {
895
        JsonArrayBuilder ldtArr = Json.createArrayBuilder();
×
896
        for(DataTable dt: ldt){
×
897
            ldtArr.add(JsonPrinter.json(dt));
×
898
        }
×
899
        return ldtArr;
×
900
    }
901

902
    public static JsonObjectBuilder json(DataTable dt) {
903
        return jsonObjectBuilder()
×
904
                .add("varQuantity", dt.getVarQuantity())
×
905
                .add("caseQuantity", dt.getCaseQuantity())
×
906
                .add("recordsPerCase", dt.getRecordsPerCase())
×
907
                .add("UNF", dt.getUnf())
×
908
                .add("dataVariables", JsonPrinter.jsonDV(dt.getDataVariables()))
×
909
                ;
910
    }
911

912
    public static JsonArrayBuilder jsonDV(List<DataVariable> dvl) {
913
        JsonArrayBuilder varArr = Json.createArrayBuilder();
×
914
        if(dvl!=null){
×
915
            for (DataVariable dv: dvl){
×
916
                varArr.add(JsonPrinter.json(dv));
×
917
            }
×
918
        }
919
        return varArr;
×
920
    }
921

922
    // TODO: add sumstat and variable categories, check formats
923
    public static JsonObjectBuilder json(DataVariable dv) {
924
    return jsonObjectBuilder()
×
925
            .add("id", dv.getId())
×
926
            .add("name", dv.getName())
×
927
            .add("label", dv.getLabel())
×
928
            .add("weighted", dv.isWeighted())
×
929
            .add("variableIntervalType", dv.getIntervalLabel())
×
930
            .add("variableFormatType", dv.getType().name()) // varFormat
×
931
            .add("formatCategory", dv.getFormatCategory())
×
932
            .add("format", dv.getFormat())
×
933
            .add("isOrderedCategorical", dv.isOrderedCategorical())
×
934
            .add("fileOrder", dv.getFileOrder())
×
935
            .add("UNF",dv.getUnf())
×
936
            .add("fileStartPosition", dv.getFileStartPosition())
×
937
            .add("fileEndPosition", dv.getFileEndPosition())
×
938
            .add("recordSegmentNumber", dv.getRecordSegmentNumber())
×
939
            .add("numberOfDecimalPoints",dv.getNumberOfDecimalPoints())
×
940
            .add("variableMetadata",jsonVarMetadata(dv.getVariableMetadatas()))
×
941
            .add("invalidRanges", dv.getInvalidRanges().isEmpty() ? null : JsonPrinter.jsonInvalidRanges(dv.getInvalidRanges()))
×
942
            .add("summaryStatistics", dv.getSummaryStatistics().isEmpty() ? null : JsonPrinter.jsonSumStat(dv.getSummaryStatistics()))
×
943
            .add("variableCategories", dv.getCategories().isEmpty() ? null : JsonPrinter.jsonCatStat(dv.getCategories()))
×
944
            ;
945
    }
946

947
    private static JsonArrayBuilder jsonInvalidRanges(Collection<VariableRange> invalidRanges) {
948
        JsonArrayBuilder invRanges = Json.createArrayBuilder();
×
949
        JsonObjectBuilder job = Json.createObjectBuilder();
×
950
        for (VariableRange vr: invalidRanges){
×
951
            job.add("beginValue", vr.getBeginValue())
×
952
            .add("hasBeginValueType", vr.getBeginValueType()!=null)
×
953
            .add("isBeginValueTypePoint", vr.isBeginValueTypePoint())
×
954
            .add("isBeginValueTypeMin", vr.isBeginValueTypeMin())
×
955
            .add("isBeginValueTypeMinExcl", vr.isBeginValueTypeMinExcl())
×
956
            .add("isBeginValueTypeMax", vr.isBeginValueTypeMax())
×
957
            .add("isBeginValueTypeMaxExcl", vr.isBeginValueTypeMaxExcl())
×
958
            .add("endValue", vr.getEndValue())
×
959
            .add("hasEndValueType", vr.getEndValueType()!=null)
×
960
            .add("endValueTypeMax", vr.isEndValueTypeMax())
×
961
            .add("endValueTypeMaxExcl", vr.isEndValueTypeMaxExcl());
×
962

963
            invRanges.add(job);
×
964
        }
×
965
        return invRanges;
×
966
    }
967

968
    private static JsonObjectBuilder jsonSumStat(Collection<SummaryStatistic> sumStat){
969
        //JsonArrayBuilder sumStatArr = Json.createArrayBuilder();
970
        JsonObjectBuilder sumStatObj = Json.createObjectBuilder();
×
971
        for (SummaryStatistic stat: sumStat){
×
972
            String label = stat.getTypeLabel()==null ? "unknown":stat.getTypeLabel();
×
973
            sumStatObj.add(label, stat.getValue());
×
974
        }
×
975
        return sumStatObj;
×
976
    }
977

978

979
    private static JsonArrayBuilder jsonCatStat(Collection<VariableCategory> catStat){
980
        JsonArrayBuilder catArr = Json.createArrayBuilder();
×
981

982
        for (VariableCategory stat: catStat){
×
983
            JsonObjectBuilder catStatObj = Json.createObjectBuilder();
×
984
            catStatObj.add("label", stat.getLabel())
×
985
                      .add("value", stat.getValue())
×
986
                      .add("isMissing", stat.isMissing());
×
987
            if(stat.getFrequency()!=null){
×
988
                catStatObj.add("frequency", stat.getFrequency());
×
989
            }
990
            catArr.add(catStatObj);
×
991
        }
×
992
        return catArr;
×
993
    }
994

995
    private static JsonArrayBuilder jsonVarGroup(List<VarGroup> varGroups) {
996
        JsonArrayBuilder vgArr = Json.createArrayBuilder();
×
997
        for (VarGroup vg : varGroups) {
×
998
            JsonObjectBuilder vgJson = jsonObjectBuilder().add("id", vg.getId()).add("label", vg.getLabel());
×
999
            JsonArrayBuilder jab = Json.createArrayBuilder();
×
1000
            for (DataVariable dvar : vg.getVarsInGroup()) {
×
1001
                jab.add(dvar.getId());
×
1002
            }
×
1003
            vgJson.add("dataVariableIds", jab);
×
1004
            vgArr.add(vgJson);
×
1005
        }
×
1006
        return vgArr;
×
1007
    }
1008

1009
    private static JsonArrayBuilder jsonVarMetadata(Collection<VariableMetadata> varMetadatas) {
1010
        JsonArrayBuilder vmArr = Json.createArrayBuilder();
×
1011
        for (VariableMetadata vm : varMetadatas) {
×
1012
            JsonObjectBuilder vmJson = jsonObjectBuilder()
×
1013
                    .add("id", vm.getId())
×
1014
                    .add("fileMetadataId", vm.getFileMetadata().getId())
×
1015
                    .add("label", vm.getLabel())
×
1016
                    .add("isWeightVar", vm.isIsweightvar())
×
1017
                    .add("isWeighted",vm.isWeighted())
×
1018
                    .add("weightVariableId", (vm.getWeightvariable()==null) ? null : vm.getWeightvariable().getId())
×
1019
                    .add("literalQuestion", vm.getLiteralquestion())
×
1020
                    .add("interviewInstruction", vm.getInterviewinstruction())
×
1021
                    .add("postQuestion", vm.getPostquestion())
×
1022
                    .add("universe", vm.getUniverse())
×
1023
                    .add("notes", vm.getNotes())
×
1024
                    .add("categoryMetadatas",json(vm.getCategoriesMetadata()));
×
1025
            JsonArrayBuilder jab = Json.createArrayBuilder();
×
1026
        }
×
1027
        return vmArr;
×
1028
    }
1029

1030
    private static JsonArrayBuilder json(Collection<CategoryMetadata> categoriesMetadata) {
1031
        JsonArrayBuilder cmArr = Json.createArrayBuilder();
×
1032
        for(CategoryMetadata cm: categoriesMetadata) {
×
1033
            JsonObjectBuilder job = jsonObjectBuilder()
×
1034
                    .add("wFreq", cm.getWfreq())
×
1035
                    .add("categoryValue", cm.getCategory().getValue());
×
1036
            cmArr.add(job);
×
1037
        }
×
1038
        return cmArr;
×
1039
    }
1040

1041
    public static JsonObjectBuilder json(HarvestingClient harvestingClient) {
1042
        if (harvestingClient == null) {
×
1043
            return null;
×
1044
        }
1045

1046
        return jsonObjectBuilder().add("nickName", harvestingClient.getName()).
×
1047
                add("dataverseAlias", harvestingClient.getDataverse().getAlias()).
×
1048
                add("type", harvestingClient.getHarvestType()).
×
1049
                add("style", harvestingClient.getHarvestStyle()).
×
1050
                add("harvestUrl", harvestingClient.getHarvestingUrl()).
×
1051
                add("archiveUrl", harvestingClient.getArchiveUrl()).
×
1052
                add("archiveDescription", harvestingClient.getArchiveDescription()).
×
1053
                add("metadataFormat", harvestingClient.getMetadataPrefix()).
×
1054
                add("set", harvestingClient.getHarvestingSet()).
×
1055
                add("schedule", harvestingClient.isScheduled() ? harvestingClient.getScheduleDescription() : "none").
×
1056
                add("status", harvestingClient.isHarvestingNow() ? "inProgress" : "inActive").
×
1057
                add("customHeaders", harvestingClient.getCustomHttpHeaders()).
×
1058
                add("allowHarvestingMissingCVV", harvestingClient.getAllowHarvestingMissingCVV()).
×
1059
                add("useOaiIdentifiersAsPids", harvestingClient.isUseOaiIdentifiersAsPids()).
×
1060
                add("lastHarvest", harvestingClient.getLastHarvestTime() == null ? null : harvestingClient.getLastHarvestTime().toString()).
×
1061
                add("lastResult", harvestingClient.getLastResult()).
×
1062
                add("lastSuccessful", harvestingClient.getLastSuccessfulHarvestTime() == null ? null : harvestingClient.getLastSuccessfulHarvestTime().toString()).
×
1063
                add("lastNonEmpty", harvestingClient.getLastNonEmptyHarvestTime() == null ? null : harvestingClient.getLastNonEmptyHarvestTime().toString()).
×
1064
                add("lastDatasetsHarvested", harvestingClient.getLastHarvestedDatasetCount()). // == null ? "N/A" : harvestingClient.getLastHarvestedDatasetCount().toString()).
×
1065
                add("lastDatasetsDeleted", harvestingClient.getLastDeletedDatasetCount()). // == null ? "N/A" : harvestingClient.getLastDeletedDatasetCount().toString()).
×
1066
                add("lastDatasetsFailed", harvestingClient.getLastFailedDatasetCount()); // == null ? "N/A" : harvestingClient.getLastFailedDatasetCount().toString());
×
1067
    }
1068

1069
    public static String format(Date d) {
1070
        return (d == null) ? null : Util.getDateTimeFormat().format(d);
1✔
1071
    }
1072

1073
    private static JsonArrayBuilder getFileCategories(FileMetadata fmd) {
1074
        if (fmd == null) {
1✔
1075
            return null;
×
1076
        }
1077
        List<String> categories = fmd.getCategoriesByName();
1✔
1078
        if (categories == null || categories.isEmpty()) {
1✔
1079
            return null;
×
1080
        }
1081
        JsonArrayBuilder fileCategories = Json.createArrayBuilder();
1✔
1082
        for (String category : categories) {
1✔
1083
            fileCategories.add(category);
1✔
1084
        }
1✔
1085
        return fileCategories;
1✔
1086
    }
1087

1088
    public static JsonArrayBuilder getTabularFileTags(DataFile df) {
1089
        if (df == null) {
1✔
1090
            return null;
×
1091
        }
1092
        List<DataFileTag> tags = df.getTags();
1✔
1093
        if (tags == null || tags.isEmpty()) {
1✔
1094
            return null;
×
1095
        }
1096
        JsonArrayBuilder tabularTags = Json.createArrayBuilder();
1✔
1097
        for (DataFileTag tag : tags) {
1✔
1098
            String label = tag.getTypeLabel();
1✔
1099
            if (label != null) {
1✔
1100
                tabularTags.add(label);
1✔
1101
            }
1102
        }
1✔
1103
        return tabularTags;
1✔
1104
    }
1105

1106
    private static class DatasetFieldsToJson implements DatasetFieldWalker.Listener {
1107

1108
        Deque<JsonObjectBuilder> objectStack = new LinkedList<>();
1✔
1109
        Deque<JsonArrayBuilder> valueArrStack = new LinkedList<>();
1✔
1110
        List<String> anonymizedFieldTypeNamesList = null;
1✔
1111
        DatasetFieldsToJson(JsonArrayBuilder result) {
1✔
1112
            valueArrStack.push(result);
1✔
1113
        }
1✔
1114

1115
        DatasetFieldsToJson(JsonArrayBuilder result, List<String> anonymizedFieldTypeNamesList) {
1116
            this(result);
1✔
1117
            this.anonymizedFieldTypeNamesList = anonymizedFieldTypeNamesList;
1✔
1118
        }
1✔
1119

1120
        @Override
1121
        public void startField(DatasetField f) {
1122
            objectStack.push(jsonObjectBuilder());
1✔
1123
            // Invariant: all values are multiple. Differentiation between multiple and single is done at endField.
1124
            valueArrStack.push(Json.createArrayBuilder());
1✔
1125

1126
            DatasetFieldType typ = f.getDatasetFieldType();
1✔
1127
            objectStack.peek().add("typeName", typ.getName());
1✔
1128
            objectStack.peek().add("multiple", typ.isAllowMultiples());
1✔
1129
            objectStack.peek().add("typeClass", typeClassString(typ));
1✔
1130
        }
1✔
1131

1132
        @Override
1133
        public void addExpandedValuesArray(DatasetField f) {
1134
            // Invariant: all values are multiple. Differentiation between multiple and single is done at endField.
1135
            valueArrStack.push(Json.createArrayBuilder());
1✔
1136
        }
1✔
1137

1138
        @Override
1139
        public void endField(DatasetField f) {
1140
            JsonObjectBuilder jsonField = objectStack.pop();
1✔
1141
            JsonArray expandedValues = valueArrStack.pop().build();
1✔
1142
            JsonArray jsonValues = valueArrStack.pop().build();
1✔
1143
            if (!jsonValues.isEmpty()) {
1✔
1144
                String datasetFieldName = f.getDatasetFieldType().getName();
1✔
1145
                if (anonymizedFieldTypeNamesList != null && anonymizedFieldTypeNamesList.contains(datasetFieldName)) {
1✔
1146
                    anonymizeField(jsonField);
1✔
1147
                } else {
1148
                    jsonField.add("value",
1✔
1149
                            f.getDatasetFieldType().isAllowMultiples() ? jsonValues
1✔
1150
                                    : jsonValues.get(0));
1✔
1151
                    if (!expandedValues.isEmpty()) {
1✔
1152
                        jsonField.add("expandedvalue",
×
1153
                                f.getDatasetFieldType().isAllowMultiples() ? expandedValues
×
1154
                                        : expandedValues.get(0));
×
1155
                    }
1156
                }
1157
                valueArrStack.peek().add(jsonField);
1✔
1158
            }
1159
        }
1✔
1160

1161
        @Override
1162
        public void externalVocabularyValue(DatasetFieldValue dsfv, JsonObject cvocEntry) {
1163
            if (dsfv.getValue() != null) {
×
1164
                if (cvocEntry.containsKey("retrieval-filtering")) {
×
1165
                    JsonObject value = datasetFieldService.getExternalVocabularyValue(dsfv.getValue());
×
1166
                    if (value!=null) {
×
1167
                        valueArrStack.peek().add(value);
×
1168
                    }
1169
                }
1170
            }
1171
        }
×
1172

1173
        @Override
1174
        public void primitiveValue(DatasetFieldValue dsfv) {
1175
            if (dsfv.getValue() != null) {
1✔
1176
                valueArrStack.peek().add(dsfv.getValue());
1✔
1177
            }
1178
        }
1✔
1179

1180
        @Override
1181
        public void controlledVocabularyValue(ControlledVocabularyValue cvv) {
1182
            valueArrStack.peek().add(cvv.getStrValue());
1✔
1183
        }
1✔
1184

1185
        @Override
1186
        public void startCompoundValue(DatasetFieldCompoundValue dsfcv) {
1187
            valueArrStack.push(Json.createArrayBuilder());
1✔
1188
        }
1✔
1189

1190
        @Override
1191
        public void endCompoundValue(DatasetFieldCompoundValue dsfcv) {
1192
            JsonArray jsonValues = valueArrStack.pop().build();
1✔
1193
            if (!jsonValues.isEmpty()) {
1✔
1194
                JsonObjectBuilder jsonField = jsonObjectBuilder();
1✔
1195
                for (JsonObject jobj : jsonValues.getValuesAs(JsonObject.class)) {
1✔
1196
                    jsonField.add(jobj.getString("typeName"), jobj);
1✔
1197
                }
1✔
1198
                valueArrStack.peek().add(jsonField);
1✔
1199
            }
1200
        }
1✔
1201

1202
        private void anonymizeField(JsonObjectBuilder jsonField) {
1203
            jsonField.add("typeClass", "primitive");
1✔
1204
            jsonField.add("value", BundleUtil.getStringFromBundle("dataset.anonymized.withheld"));
1✔
1205
            jsonField.add("multiple", false);
1✔
1206
        }
1✔
1207
    }
1208

1209
    public static JsonObjectBuilder json(AuthenticationProviderRow aRow) {
1210
        return jsonObjectBuilder()
×
1211
                        .add("id", aRow.getId())
×
1212
                        .add("factoryAlias", aRow.getFactoryAlias() )
×
1213
                        .add("title", aRow.getTitle())
×
1214
                        .add("subtitle",aRow.getSubtitle())
×
1215
                        .add("factoryData", aRow.getFactoryData())
×
1216
                        .add("enabled", aRow.isEnabled())
×
1217
                ;
1218
    }
1219

1220
    public static JsonObjectBuilder json(PrivateUrl privateUrl) {
1221
        return jsonObjectBuilder()
1✔
1222
                // We provide the token here as a convenience even though it is also in the role assignment.
1223
                .add("token", privateUrl.getToken())
1✔
1224
                .add("link", privateUrl.getLink())
1✔
1225
                .add("roleAssignment", json(privateUrl.getRoleAssignment()));
1✔
1226
    }
1227

1228
    public static JsonObjectBuilder json( ExplicitGroup eg ) {
1229
        JsonArrayBuilder ras = Json.createArrayBuilder();
×
1230
            for (String u : eg.getContainedRoleAssgineeIdentifiers()) {
×
1231
                ras.add(u);
×
1232
            }
×
1233
            return jsonObjectBuilder()
×
1234
                    .add("identifier", eg.getIdentifier())
×
1235
                    .add("groupAliasInOwner", eg.getGroupAliasInOwner())
×
1236
                    .add("owner", eg.getOwner().getId())
×
1237
                    .add("description", eg.getDescription())
×
1238
                    .add("displayName", eg.getDisplayName())
×
1239
                    .add("containedRoleAssignees", ras);
×
1240
    }
1241

1242
    public static JsonArrayBuilder jsonDataverseFacets(List<DataverseFacet> dataverseFacets) {
1243
        JsonArrayBuilder dataverseFacetsJson = Json.createArrayBuilder();
×
1244
        for(DataverseFacet facet: dataverseFacets) {
×
1245
            dataverseFacetsJson.add(json(facet));
×
1246
        }
×
1247
        return dataverseFacetsJson;
×
1248
    }
1249

1250
    public static JsonObjectBuilder json(DataverseFacet aFacet) {
1251
        return jsonObjectBuilder()
×
1252
                    .add("id", String.valueOf(aFacet.getId())) // TODO should just be id I think
×
1253
                    .add("displayName", aFacet.getDatasetFieldType().getDisplayName())
×
1254
                    .add("name", aFacet.getDatasetFieldType().getName());
×
1255
    }
1256

1257
    public static JsonObjectBuilder json(Embargo embargo) {
1258
        return jsonObjectBuilder().add("dateAvailable", embargo.getDateAvailable().toString()).add("reason",
1✔
1259
                embargo.getReason());
1✔
1260
    }
1261

1262
    public static JsonObjectBuilder json(Retention retention) {
1263
        return jsonObjectBuilder().add("dateUnavailable", retention.getDateUnavailable().toString()).add("reason",
×
1264
                retention.getReason());
×
1265
    }
1266

1267
    public static JsonObjectBuilder json(License license) {
1268
        return jsonObjectBuilder()
×
1269
            .add("id", license.getId())
×
1270
            .add("name", license.getName())
×
1271
            .add("shortDescription", license.getShortDescription())
×
1272
            .add("uri", license.getUri().toString())
×
1273
            .add("iconUrl", license.getIconUrl() == null ? null : license.getIconUrl().toString())
×
1274
            .add("active", license.isActive())
×
1275
            .add("isDefault", license.isDefault())
×
1276
            .add("sortOrder", license.getSortOrder());
×
1277
    }
1278

1279
    public static Collector<String, JsonArrayBuilder, JsonArrayBuilder> stringsToJsonArray() {
1280
        return new Collector<String, JsonArrayBuilder, JsonArrayBuilder>() {
×
1281

1282
            @Override
1283
            public Supplier<JsonArrayBuilder> supplier() {
1284
                return () -> Json.createArrayBuilder();
×
1285
            }
1286

1287
            @Override
1288
            public BiConsumer<JsonArrayBuilder, String> accumulator() {
1289
                return (JsonArrayBuilder b, String s) -> b.add(s);
×
1290
            }
1291

1292
            @Override
1293
            public BinaryOperator<JsonArrayBuilder> combiner() {
1294
                return (jab1, jab2) -> {
×
1295
                    JsonArrayBuilder retVal = Json.createArrayBuilder();
×
1296
                    jab1.build().forEach(retVal::add);
×
1297
                    jab2.build().forEach(retVal::add);
×
1298
                    return retVal;
×
1299
                };
1300
            }
1301

1302
            @Override
1303
            public Function<JsonArrayBuilder, JsonArrayBuilder> finisher() {
1304
                return Function.identity();
×
1305
            }
1306

1307
            @Override
1308
            public Set<Collector.Characteristics> characteristics() {
1309
                return EnumSet.of(Collector.Characteristics.IDENTITY_FINISH);
×
1310
            }
1311
        };
1312
    }
1313

1314
    public static JsonObjectBuilder json(Map<String, Long> map) {
1315
        JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
×
1316
        for (Map.Entry<String, Long> mapEntry : map.entrySet()) {
×
1317
            jsonObjectBuilder.add(mapEntry.getKey(), mapEntry.getValue());
×
1318
        }
×
1319
        return jsonObjectBuilder;
×
1320
    }
1321

1322
    public static JsonObjectBuilder jsonFileCountPerAccessStatusMap(Map<FileSearchCriteria.FileAccessStatus, Long> map) {
1323
        JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
×
1324
        for (Map.Entry<FileSearchCriteria.FileAccessStatus, Long> mapEntry : map.entrySet()) {
×
1325
            jsonObjectBuilder.add(mapEntry.getKey().toString(), mapEntry.getValue());
×
1326
        }
×
1327
        return jsonObjectBuilder;
×
1328
    }
1329

1330
    public static JsonObjectBuilder jsonFileCountPerTabularTagNameMap(Map<DataFileTag.TagType, Long> map) {
1331
        JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
×
1332
        for (Map.Entry<DataFileTag.TagType, Long> mapEntry : map.entrySet()) {
×
1333
            jsonObjectBuilder.add(mapEntry.getKey().toString(), mapEntry.getValue());
×
1334
        }
×
1335
        return jsonObjectBuilder;
×
1336
    }
1337

1338
    public static Collector<JsonObjectBuilder, ArrayList<JsonObjectBuilder>, JsonArrayBuilder> toJsonArray() {
1339
        return new Collector<JsonObjectBuilder, ArrayList<JsonObjectBuilder>, JsonArrayBuilder>() {
×
1340

1341
            @Override
1342
            public Supplier<ArrayList<JsonObjectBuilder>> supplier() {
1343
                return () -> new ArrayList<>();
×
1344
            }
1345

1346
            @Override
1347
            public BiConsumer<ArrayList<JsonObjectBuilder>, JsonObjectBuilder> accumulator() {
1348
                return (t, u) ->t.add(u);
×
1349
            }
1350

1351
            @Override
1352
            public BinaryOperator<ArrayList<JsonObjectBuilder>> combiner() {
1353
                return (jab1, jab2) -> {
×
1354
                    jab1.addAll(jab2);
×
1355
                    return jab1;
×
1356
                };
1357
            }
1358

1359
            @Override
1360
            public Function<ArrayList<JsonObjectBuilder>, JsonArrayBuilder> finisher() {
1361
                return (l) -> {
×
1362
                  JsonArrayBuilder bld = Json.createArrayBuilder();
×
1363
                  l.forEach( bld::add );
×
1364
                  return bld;
×
1365
                };
1366
            }
1367

1368
            @Override
1369
            public Set<Collector.Characteristics> characteristics() {
1370
                return Collections.emptySet();
×
1371
            }
1372
        };
1373
    }
1374

1375
    public static String getMd5IfItExists(DataFile.ChecksumType checksumType, String checksumValue) {
1376
        if (DataFile.ChecksumType.MD5.equals(checksumType)) {
1✔
1377
            return checksumValue;
×
1378
        } else {
1379
            return null;
1✔
1380
        }
1381
    }
1382

1383
    public static JsonObjectBuilder getChecksumTypeAndValue(DataFile.ChecksumType checksumType, String checksumValue) {
1384
        if (checksumType != null) {
1✔
1385
            return Json.createObjectBuilder()
×
1386
                    .add("type", checksumType.toString())
×
1387
                    .add("value", checksumValue);
×
1388
        } else {
1389
            return null;
1✔
1390
        }
1391
    }
1392

1393
    /**
1394
     * Takes a map, returns a Json object for this map.
1395
     * If map is {@code null}, returns {@code null}.
1396
     * @param in the map to be translated
1397
     * @return a Json Builder of the map, or {@code null}.
1398
     */
1399
    public static JsonObjectBuilder mapToObject(Map<String,String> in) {
1400
        if ( in == null ) return null;
×
1401
        JsonObjectBuilder b = jsonObjectBuilder();
×
1402
        in.keySet().forEach( k->b.add(k, in.get(k)) );
×
1403
        return b;
×
1404
    }
1405

1406

1407
    /**
1408
     * Get signposting from Dataset
1409
     * @param ds the designated Dataset
1410
     * @return json linkset
1411
     */
1412
    public static JsonObjectBuilder jsonLinkset(Dataset ds) {
1413
        return jsonObjectBuilder()
×
1414
                .add("anchor", ds.getPersistentURL())
×
1415
                .add("cite-as", Json.createArrayBuilder().add(jsonObjectBuilder().add("href", ds.getPersistentURL())))
×
1416
                .add("type", Json.createArrayBuilder().add(jsonObjectBuilder().add("href", "https://schema.org/AboutPage")))
×
1417
                .add("author", ds.getPersistentURL())
×
1418
                .add("protocol", ds.getProtocol())
×
1419
                .add("authority", ds.getAuthority())
×
1420
                .add("publisher", BrandingUtil.getInstallationBrandName())
×
1421
                .add("publicationDate", ds.getPublicationDateFormattedYYYYMMDD())
×
1422
                .add("storageIdentifier", ds.getStorageIdentifier());
×
1423
    }
1424

1425
    private static JsonObjectBuilder jsonLicense(DatasetVersion dsv) {
1426
        JsonObjectBuilder licenseJsonObjectBuilder = jsonObjectBuilder()
×
1427
                .add("name", DatasetUtil.getLicenseName(dsv))
×
1428
                .add("uri", DatasetUtil.getLicenseURI(dsv));
×
1429
        String licenseIconUri = DatasetUtil.getLicenseIcon(dsv);
×
1430
        if (licenseIconUri != null) {
×
1431
            licenseJsonObjectBuilder.add("iconUri", licenseIconUri);
×
1432
        }
1433
        return licenseJsonObjectBuilder;
×
1434
    }
1435

1436
    public static JsonArrayBuilder jsonDataverseFieldTypeInputLevels(List<DataverseFieldTypeInputLevel> inputLevels) {
1437
        JsonArrayBuilder jsonArrayOfInputLevels = Json.createArrayBuilder();
×
1438
        for (DataverseFieldTypeInputLevel inputLevel : inputLevels) {
×
1439
            NullSafeJsonBuilder inputLevelJsonObject = NullSafeJsonBuilder.jsonObjectBuilder();
×
1440
            inputLevelJsonObject.add("datasetFieldTypeName", inputLevel.getDatasetFieldType().getName());
×
1441
            inputLevelJsonObject.add("required", inputLevel.isRequired());
×
1442
            inputLevelJsonObject.add("include", inputLevel.isInclude());
×
1443
            jsonArrayOfInputLevels.add(inputLevelJsonObject);
×
1444
        }
×
1445
        return jsonArrayOfInputLevels;
×
1446
    }
1447

1448
    public static JsonArrayBuilder jsonDataverseInputLevels(List<DataverseFieldTypeInputLevel> inputLevels) {
1449
        JsonArrayBuilder inputLevelsArrayBuilder = Json.createArrayBuilder();
×
1450
        for (DataverseFieldTypeInputLevel inputLevel : inputLevels) {
×
1451
            inputLevelsArrayBuilder.add(jsonDataverseInputLevel(inputLevel));
×
1452
        }
×
1453
        return inputLevelsArrayBuilder;
×
1454
    }
1455

1456
    private static JsonObjectBuilder jsonDataverseInputLevel(DataverseFieldTypeInputLevel inputLevel) {
1457
        JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
×
1458
        jsonObjectBuilder.add("datasetFieldTypeName", inputLevel.getDatasetFieldType().getName());
×
1459
        jsonObjectBuilder.add("required", inputLevel.isRequired());
×
1460
        jsonObjectBuilder.add("include", inputLevel.isInclude());
×
1461
        return jsonObjectBuilder;
×
1462
    }
1463

1464
    public static JsonArrayBuilder jsonDataverseFeaturedItems(List<DataverseFeaturedItem> dataverseFeaturedItems) {
1465
        JsonArrayBuilder featuredItemsArrayBuilder = Json.createArrayBuilder();
×
1466
        for (DataverseFeaturedItem dataverseFeaturedItem : dataverseFeaturedItems) {
×
1467
            featuredItemsArrayBuilder.add(json(dataverseFeaturedItem));
×
1468
        }
×
1469
        return featuredItemsArrayBuilder;
×
1470
    }
1471

1472
    public static JsonObjectBuilder json(DataverseFeaturedItem dataverseFeaturedItem) {
1473
        return jsonObjectBuilder()
×
1474
                .add("id", dataverseFeaturedItem.getId())
×
1475
                .add("content", dataverseFeaturedItem.getContent())
×
1476
                .add("imageFileName", dataverseFeaturedItem.getImageFileName())
×
1477
                .add("imageFileUrl", dataverseFeaturedItem.getImageFileUrl())
×
1478
                .add("displayOrder", dataverseFeaturedItem.getDisplayOrder());
×
1479
    }
1480
}
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

© 2025 Coveralls, Inc