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

IQSS / dataverse / #23048

03 Sep 2024 05:39PM UTC coverage: 20.761% (+0.002%) from 20.759%
#23048

Pull #10820

github

landreev
added a size == 0 check to DatasetUtil.getThumbnail (copied from #10687) #10819
Pull Request #10820: A Fix for the Dataset Thumbnail Bug on Publish, 10819

3 of 38 new or added lines in 4 files covered. (7.89%)

1 existing line in 1 file now uncovered.

17527 of 84424 relevant lines covered (20.76%)

0.21 hits per line

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

46.28
/src/main/java/edu/harvard/iq/dataverse/Dataset.java
1
package edu.harvard.iq.dataverse;
2

3
import edu.harvard.iq.dataverse.dataset.DatasetThumbnail;
4
import edu.harvard.iq.dataverse.dataset.DatasetUtil;
5
import edu.harvard.iq.dataverse.harvest.client.HarvestingClient;
6
import edu.harvard.iq.dataverse.license.License;
7
import edu.harvard.iq.dataverse.makedatacount.DatasetExternalCitations;
8
import edu.harvard.iq.dataverse.makedatacount.DatasetMetrics;
9
import edu.harvard.iq.dataverse.settings.FeatureFlags;
10
import java.nio.file.Path;
11
import java.nio.file.Paths;
12
import java.sql.Timestamp;
13
import java.text.SimpleDateFormat;
14
import java.util.ArrayList;
15
import java.util.Collection;
16
import java.util.Date;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Objects;
20
import java.util.Set;
21
import jakarta.persistence.CascadeType;
22
import jakarta.persistence.Entity;
23
import jakarta.persistence.Index;
24
import jakarta.persistence.JoinColumn;
25
import jakarta.persistence.ManyToOne;
26
import jakarta.persistence.NamedQueries;
27
import jakarta.persistence.NamedQuery;
28
import jakarta.persistence.NamedStoredProcedureQuery;
29
import jakarta.persistence.OneToMany;
30
import jakarta.persistence.OneToOne;
31
import jakarta.persistence.OrderBy;
32
import jakarta.persistence.ParameterMode;
33
import jakarta.persistence.StoredProcedureParameter;
34
import jakarta.persistence.Table;
35
import jakarta.persistence.Temporal;
36
import jakarta.persistence.TemporalType;
37

38
import edu.harvard.iq.dataverse.settings.JvmSettings;
39
import edu.harvard.iq.dataverse.storageuse.StorageUse;
40
import edu.harvard.iq.dataverse.util.StringUtil;
41
import edu.harvard.iq.dataverse.util.SystemConfig;
42

43
/**
44
 *
45
 * @author skraffmiller
46
 */
47
@NamedQueries({
48
    // Dataset.findById should only be used if you're going to iterate over files (otherwise, lazy loading in DatasetService.find() is better).
49
    // If you are going to iterate over files, preferably call the DatasetService.findDeep() method i.s.o. using this query directly.
50
    @NamedQuery(name = "Dataset.findById", 
51
                query = "SELECT o FROM Dataset o LEFT JOIN FETCH o.files WHERE o.id=:id"),
52
    @NamedQuery(name = "Dataset.findIdStale",
53
               query = "SELECT d.id FROM Dataset d WHERE d.indexTime is NULL OR d.indexTime < d.modificationTime"),
54
    @NamedQuery(name = "Dataset.findIdStalePermission",
55
               query = "SELECT d.id FROM Dataset d WHERE d.permissionIndexTime is NULL OR d.permissionIndexTime < d.permissionModificationTime"),
56
    @NamedQuery(name = "Dataset.findByIdentifier",
57
               query = "SELECT d FROM Dataset d WHERE d.identifier=:identifier"),
58
    @NamedQuery(name = "Dataset.findByIdentifierAuthorityProtocol",
59
               query = "SELECT d FROM Dataset d WHERE d.identifier=:identifier AND d.protocol=:protocol AND d.authority=:authority"),
60
    @NamedQuery(name = "Dataset.findIdentifierByOwnerId", 
61
                query = "SELECT o.identifier FROM Dataset o WHERE o.owner.id=:ownerId"),
62
    @NamedQuery(name = "Dataset.findIdByOwnerId", 
63
                query = "SELECT o.id FROM Dataset o WHERE o.owner.id=:ownerId"),
64
    @NamedQuery(name = "Dataset.findByOwnerId", 
65
                query = "SELECT o FROM Dataset o WHERE o.owner.id=:ownerId"),
66
    @NamedQuery(name = "Dataset.findByCreatorId",
67
                query = "SELECT o FROM Dataset o WHERE o.creator.id=:creatorId"),
68
    @NamedQuery(name = "Dataset.findByReleaseUserId",
69
                query = "SELECT o FROM Dataset o WHERE o.releaseUser.id=:releaseUserId"),
70
})
71

72
/*
73
    Below is the database stored procedure for getting a string dataset id.
74
    Used when the Dataverse is (optionally) configured to use
75
    procedurally generated values for dataset ids, instead of the default
76
    random strings. 
77

78
    The use of a stored procedure to create an identifier is explained in the
79
    installation documentation (where an example script is supplied).
80
    The stored procedure can be implemented using other SQL flavors -
81
    without having to modify the application code. 
82
            -- L.A. 4.6.2 (modified by C.S. for version 5.4.1+)
83
*/ 
84
@NamedStoredProcedureQuery(
85
        name = "Dataset.generateIdentifierFromStoredProcedure",
86
        procedureName = "generateIdentifierFromStoredProcedure",
87
        parameters = {
88
            @StoredProcedureParameter(mode = ParameterMode.OUT, type = String.class)
89
        }
90
)
91
@Entity
92
@Table(indexes = {
93
    @Index(columnList = "guestbook_id"),
94
    @Index(columnList = "thumbnailfile_id")})
95
public class Dataset extends DvObjectContainer {
96

97
    public static final String TARGET_URL = "/citation?persistentId=";
98
    private static final long serialVersionUID = 1L;
99

100
    @OneToMany(mappedBy = "owner", cascade = CascadeType.MERGE)
1✔
101
    @OrderBy("id")
102
    private List<DataFile> files = new ArrayList<>();
103

104
    @Temporal(value = TemporalType.TIMESTAMP)
105
    private Date lastExportTime;
106

107
    
108
    @OneToMany(mappedBy = "dataset", orphanRemoval = true, cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
1✔
109
    @OrderBy("versionNumber DESC, minorVersionNumber DESC")
110
    private List<DatasetVersion> versions = new ArrayList<>();
111

112
    @OneToMany(mappedBy = "dataset", cascade = CascadeType.ALL, orphanRemoval = true)
113
    private Set<DatasetLock> datasetLocks;
114
    
115
    @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
116
    @JoinColumn(name = "thumbnailfile_id")
117
    private DataFile thumbnailFile;
118
    
119
    @OneToMany(mappedBy = "dataset", orphanRemoval = true, cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
1✔
120
    private List<DatasetMetrics> datasetMetrics = new ArrayList<>(); 
121
    
122
    @OneToMany(mappedBy = "dataset", orphanRemoval = true, cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
1✔
123
    private List<DatasetExternalCitations> datasetExternalCitations = new ArrayList<>(); 
124
    
125
    /**
126
     * By default, Dataverse will attempt to show unique thumbnails for datasets
127
     * based on images that have been uploaded to them. Setting this to true
128
     * will result in a generic dataset thumbnail appearing instead.
129
     */
130
    private boolean useGenericThumbnail;
131

132
    @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
133
    @JoinColumn(name = "guestbook_id", unique = false, nullable = true, insertable = true, updatable = true)
134
    private Guestbook guestbook;
135
    
136
    @OneToMany(mappedBy="dataset", cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
137
    private List<DatasetLinkingDataverse> datasetLinkingDataverses;
138

139
    public List<DatasetLinkingDataverse> getDatasetLinkingDataverses() {
140
        return datasetLinkingDataverses;
1✔
141
    }
142

143
    public void setDatasetLinkingDataverses(List<DatasetLinkingDataverse> datasetLinkingDataverses) {
144
        this.datasetLinkingDataverses = datasetLinkingDataverses;
×
145
    }
×
146

147
    private boolean fileAccessRequest;
148
    @OneToMany(mappedBy = "dataset", orphanRemoval = true, cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
1✔
149
    private List<DataFileCategory> dataFileCategories = null;
150
    
151
    @ManyToOne
152
    @JoinColumn(name = "citationDateDatasetFieldType_id")
153
    private DatasetFieldType citationDateDatasetFieldType;
154
    
155
    public DatasetFieldType getCitationDateDatasetFieldType() {
156
        return citationDateDatasetFieldType;
1✔
157
    }
158

159
    public void setCitationDateDatasetFieldType(DatasetFieldType citationDateDatasetFieldType) {
160
        this.citationDateDatasetFieldType = citationDateDatasetFieldType;
×
161
    }    
×
162

163
    // Per DataCite best practices, the citation date of a dataset may need 
164
    // to be adjusted to reflect the latest embargo availability date of any 
165
    // file within the first published version. 
166
    // If any files are embargoed in the first version, this date will be
167
    // calculated and cached here upon its publication, in the 
168
    // FinalizeDatasetPublicationCommand. 
169
    private Timestamp embargoCitationDate;
170
    
171
    public Timestamp getEmbargoCitationDate() {
172
        return embargoCitationDate;
×
173
    }
174

175
    public void setEmbargoCitationDate(Timestamp embargoCitationDate) {
176
        this.embargoCitationDate = embargoCitationDate;
×
177
    }
×
178
    
179
    
180
    
181
    @ManyToOne
182
    @JoinColumn(name="template_id",nullable = true)
183
    private Template template;
184
    
185
    public Template getTemplate() {
186
        return template;
×
187
    }
188

189
    public void setTemplate(Template template) {
190
        this.template = template;
×
191
    }
×
192

193
    public Dataset() {
194
        this(false);
1✔
195
    }
1✔
196
    
197
    public Dataset(boolean isHarvested) {
1✔
198
        DatasetVersion datasetVersion = new DatasetVersion();
1✔
199
        datasetVersion.setDataset(this);
1✔
200
        datasetVersion.setVersionState(DatasetVersion.VersionState.DRAFT);
1✔
201
        datasetVersion.setFileMetadatas(new ArrayList<>());
1✔
202
        datasetVersion.setVersionNumber((long) 1);
1✔
203
        datasetVersion.setMinorVersionNumber((long) 0);
1✔
204
        versions.add(datasetVersion);
1✔
205
        
206
        if (!isHarvested) {
1✔
207
            StorageUse storageUse = new StorageUse(this); 
1✔
208
            this.setStorageUse(storageUse);
1✔
209
        }
210
        
211
        if (FeatureFlags.DISABLE_DATASET_THUMBNAIL_AUTOSELECT.enabled()) {
1✔
NEW
212
            this.setUseGenericThumbnail(true);
×
213
        }
214
    }
1✔
215
    
216
    /**
217
     * Checks whether {@code this} dataset is locked for a given reason.
218
     * @param reason the reason we test for.
219
     * @return {@code true} iff the data set is locked for {@code reason}.
220
     */
221
    public boolean isLockedFor( DatasetLock.Reason reason ) {
222
        for ( DatasetLock l : getLocks() ) {
1✔
223
            if ( l.getReason() == reason ) {
1✔
224
                return true;
1✔
225
            }
226
        }
1✔
227
        return false;
1✔
228
    }
229
    
230
    /**
231
     * Retrieves the dataset lock for the passed reason. 
232
     * @param reason
233
     * @return the dataset lock, or {@code null}.
234
     */
235
    public DatasetLock getLockFor( DatasetLock.Reason reason ) {
236
        for ( DatasetLock l : getLocks() ) {
1✔
237
            if ( l.getReason() == reason ) {
1✔
238
                return l;
1✔
239
            }
240
        }
1✔
241
        return null;
1✔
242
    }
243
    
244
    public Set<DatasetLock> getLocks() {
245
        // lazy set creation
246
        if ( datasetLocks == null ) {
1✔
247
            datasetLocks = new HashSet<>();
1✔
248
        }
249
        return datasetLocks;
1✔
250
    }
251

252
    /**
253
     * JPA use only!
254
     * @param datasetLocks 
255
     */
256
    void setLocks(Set<DatasetLock> datasetLocks) {
257
        this.datasetLocks = datasetLocks;
×
258
    }
×
259
    
260
    public void addLock(DatasetLock datasetLock) {
261
        getLocks().add(datasetLock);
1✔
262
    }
1✔
263
    
264
    public void removeLock( DatasetLock aDatasetLock ) {
265
        getLocks().remove( aDatasetLock );
1✔
266
    }
1✔
267

268
    public boolean isLocked() {
269
        return !getLocks().isEmpty();
1✔
270
    }
271
    
272
    public Date getLastExportTime() {
273
        return lastExportTime;
×
274
    }
275

276
    public void setLastExportTime(Date lastExportTime) {
277
        this.lastExportTime = lastExportTime;
×
278
    }
×
279
    
280
    public Guestbook getGuestbook() {
281
        return guestbook;
1✔
282
    }
283

284
    public void setGuestbook(Guestbook guestbook) {
285
        this.guestbook = guestbook;
1✔
286
    }
1✔
287

288
    public boolean isFileAccessRequest() {
289
        return fileAccessRequest;
×
290
    }
291

292
    public void setFileAccessRequest(boolean fileAccessRequest) {
293
        this.fileAccessRequest = fileAccessRequest;
×
294
    }
×
295

296
    public String getPersistentURL() {
297
        return this.getGlobalId().asURL();
1✔
298
    }
299
    
300
    public List<DataFile> getFiles() {
301
        return files;
1✔
302
    }
303

304
    public void setFiles(List<DataFile> files) {
305
        this.files = files;
1✔
306
    }
1✔
307

308
    public boolean isDeaccessioned() {
309
        // return true, if all published versions were deaccessioned
310
        boolean hasDeaccessionedVersions = false;
1✔
311
        for (DatasetVersion testDsv : getVersions()) {
1✔
312
            if (testDsv.isReleased()) {
1✔
313
                return false;
1✔
314
            }
315
            // Also check for draft version
316
            if (testDsv.isDraft()) {
1✔
317
                return false;
1✔
318
            }
319
            if (testDsv.isDeaccessioned()) {
1✔
320
                hasDeaccessionedVersions = true;
1✔
321
            }
322
        }
1✔
323
        return hasDeaccessionedVersions; // since any published version would have already returned
1✔
324
    }
325
    
326

327
    public DatasetVersion getLatestVersion() {
328
        return getVersions().get(0);
1✔
329
    }
330

331
    public DatasetVersion getLatestVersionForCopy() {
332
        for (DatasetVersion testDsv : getVersions()) {
1✔
333
            if (testDsv.isReleased() || testDsv.isArchived()) {
1✔
334
                return testDsv;
1✔
335
            }
336
        }
×
337
        return getVersions().get(0);
×
338
    }
339

340
    public List<DatasetVersion> getVersions() {
341
        return versions;
1✔
342
    }
343

344
    public void setVersions(List<DatasetVersion> versions) {
345
        this.versions = versions;
1✔
346
    }
1✔
347

348
    private DatasetVersion createNewDatasetVersion(Template template, FileMetadata fmVarMet) {
349
        
350
        DatasetVersion dsv = new DatasetVersion();
1✔
351
        dsv.setVersionState(DatasetVersion.VersionState.DRAFT);
1✔
352
        dsv.setFileMetadatas(new ArrayList<>());
1✔
353
        DatasetVersion latestVersion;
354

355
        //if the latest version has values get them copied over
356
        if (template != null) {
1✔
357
            dsv.updateDefaultValuesFromTemplate(template);
×
358
            setVersions(new ArrayList<>());
×
359
        } else {
360
            latestVersion = getLatestVersionForCopy();
1✔
361
            
362
            if (latestVersion.getUNF() != null){
1✔
363
                dsv.setUNF(latestVersion.getUNF());
×
364
            }
365
            
366
            if (latestVersion.getDatasetFields() != null && !latestVersion.getDatasetFields().isEmpty()) {
1✔
367
                dsv.setDatasetFields(dsv.copyDatasetFields(latestVersion.getDatasetFields()));
1✔
368
            }
369
            /*
370
            adding file metadatas here and updating terms
371
            because the terms need to know about the files
372
            in a pre-save validation SEK 12/6/2021
373
            */
374
            for (FileMetadata fm : latestVersion.getFileMetadatas()) {
1✔
375
                FileMetadata newFm = new FileMetadata();
1✔
376
                // TODO: 
377
                // the "category" will be removed, shortly. 
378
                // (replaced by multiple, tag-like categories of 
379
                // type DataFileCategory) -- L.A. beta 10
380
                //newFm.setCategory(fm.getCategory());
381
                // yep, these are the new categories:
382
                newFm.setCategories(fm.getCategories());
1✔
383
                newFm.setDescription(fm.getDescription());
1✔
384
                newFm.setLabel(fm.getLabel());
1✔
385
                newFm.setDirectoryLabel(fm.getDirectoryLabel());
1✔
386
                newFm.setRestricted(fm.isRestricted());
1✔
387
                newFm.setDataFile(fm.getDataFile());
1✔
388
                newFm.setDatasetVersion(dsv);
1✔
389
                newFm.setProvFreeForm(fm.getProvFreeForm());
1✔
390
                newFm.setInPriorVersion(true);
1✔
391

392
                //fmVarMet would be updated in DCT
393
                if ((fmVarMet != null && !fmVarMet.getId().equals(fm.getId())) || (fmVarMet == null))  {
1✔
394
                    if (fm.getVariableMetadatas() != null) {
1✔
395
                        newFm.copyVariableMetadata(fm.getVariableMetadatas());
1✔
396
                    }
397
                    if (fm.getVarGroups() != null) {
1✔
398
                        newFm.copyVarGroups(fm.getVarGroups());
1✔
399
                    }
400
                }
401
                
402
                dsv.getFileMetadatas().add(newFm);
1✔
403
            }
1✔
404
            
405
            if (latestVersion.getTermsOfUseAndAccess()!= null){
1✔
406
                TermsOfUseAndAccess terms = latestVersion.getTermsOfUseAndAccess().copyTermsOfUseAndAccess();
×
407
                terms.setDatasetVersion(dsv);
×
408
                dsv.setTermsOfUseAndAccess(terms);
×
409
            } else {
×
410
                TermsOfUseAndAccess terms = new TermsOfUseAndAccess();
1✔
411
                terms.setDatasetVersion(dsv);
1✔
412
                terms.setLicense(null);
1✔
413
                terms.setFileAccessRequest(true);
1✔
414
                dsv.setTermsOfUseAndAccess(terms);
1✔
415
            }
416
        }
417

418
        // I'm adding the version to the list so it will be persisted when
419
        // the study object is persisted.
420
        if (template == null) {
1✔
421
            getVersions().add(0, dsv);
1✔
422
        } else {
423
            this.setVersions(new ArrayList<>());
×
424
            getVersions().add(0, dsv);
×
425
        }
426

427
        dsv.setDataset(this);
1✔
428
        return dsv;
1✔
429
    }
430

431
    /**
432
     * The "edit version" is the most recent *draft* of a dataset, and if the
433
     * latest version of a dataset is published, a new draft will be created. If
434
     * you don't want to create a new version, you should be using
435
     * getLatestVersion.
436
     *
437
     * @return The edit version {@code this}.
438
     */
439
    public DatasetVersion getOrCreateEditVersion() {
440
        return getOrCreateEditVersion(null, null);
1✔
441
    }
442

443
    public DatasetVersion getOrCreateEditVersion(FileMetadata fm) {
444
        return getOrCreateEditVersion(null, fm);
×
445
    }
446

447
    public DatasetVersion getOrCreateEditVersion(Template template, FileMetadata fm) {
448
        DatasetVersion latestVersion = this.getLatestVersion();
1✔
449
        if (!latestVersion.isWorkingCopy() || template != null) {
1✔
450
            // if the latest version is released or archived, create a new version for editing
451
            return createNewDatasetVersion(template, fm);
1✔
452
        } else {
453
            // else, edit existing working copy
454
            return latestVersion;
1✔
455
        }
456
    }
457

458
    /*
459
     * @todo Investigate if this method should be deprecated in favor of
460
     * createNewDatasetVersion.
461
     */
462
    public DatasetVersion getCreateVersion(License license) {
463
        DatasetVersion dsv = new DatasetVersion();
1✔
464
        dsv.setVersionState(DatasetVersion.VersionState.DRAFT);
1✔
465
        dsv.setDataset(this);
1✔
466
        dsv.initDefaultValues(license);
1✔
467
        this.setVersions(new ArrayList<>());
1✔
468
        getVersions().add(0, dsv);
1✔
469
        return dsv;
1✔
470
    }
471

472
    public Date getMostRecentMajorVersionReleaseDate() {
473
        if (this.isHarvested()) {
1✔
474
            return getVersions().get(0).getReleaseTime();
×
475
        } else {
476
            for (DatasetVersion version : this.getVersions()) {
1✔
477
                if (version.isReleased() && version.getMinorVersionNumber().equals((long) 0)) {
1✔
478
                    return version.getReleaseTime();
×
479
                }
480
            }
1✔
481
            return null;
1✔
482
        }
483
    }
484

485
    public DatasetVersion getReleasedVersion() {
486
        for (DatasetVersion version : this.getVersions()) {
1✔
487
            if (version.isReleased()) {
1✔
488
                return version;
×
489
            }
490
        }
1✔
491
        return null;
1✔
492
    }
493
    
494
    public DatasetVersion getVersionFromId(Long datasetVersionId) {
495
        for (DatasetVersion version : this.getVersions()) {
×
496
            if (datasetVersionId == version.getId().longValue()) {
×
497
                return version;
×
498
            }
499
        }
×
500
        return null;
×
501
    }
502

503
    public List<DataFileCategory> getCategories() {
504
        return dataFileCategories;
1✔
505
    }
506

507
    public void setFileCategories(List<DataFileCategory> categories) {
508
        this.dataFileCategories = categories;
×
509
    }
×
510

511
    public void addFileCategory(DataFileCategory category) {
512
        if (dataFileCategories == null) {
1✔
513
            dataFileCategories = new ArrayList<>();
1✔
514
        }
515
        dataFileCategories.add(category);
1✔
516
    }
1✔
517

518
    public void setCategoriesByName(List<String> newCategoryNames) {
519
        if (newCategoryNames != null) {
1✔
520
            Collection<String> oldCategoryNames = getCategoryNames();
1✔
521

522
            for (String newCategoryName : newCategoryNames) {
1✔
523
                if (!oldCategoryNames.contains(newCategoryName)) {
1✔
524
                    DataFileCategory newCategory = new DataFileCategory();
1✔
525
                    newCategory.setName(newCategoryName);
1✔
526
                    newCategory.setDataset(this);
1✔
527
                    this.addFileCategory(newCategory);
1✔
528
                }
529
            }
1✔
530
        }
531
    }
1✔
532

533
    public DataFileCategory getCategoryByName(String categoryName) {
534
        if (categoryName != null && !categoryName.isEmpty()) {
×
535
            if (dataFileCategories != null) {
×
536
                for (DataFileCategory dataFileCategory : dataFileCategories) {
×
537
                    if (categoryName.equals(dataFileCategory.getName())) {
×
538
                        return dataFileCategory;
×
539
                    }
540
                }
×
541
            }
542

543
            DataFileCategory newCategory = new DataFileCategory();
×
544
            newCategory.setName(categoryName);
×
545
            newCategory.setDataset(this);
×
546
            this.addFileCategory(newCategory);
×
547

548
            return newCategory;
×
549
        }
550
        return null;
×
551
    }
552

553
    private Collection<String> getCategoryNames() {
554
        if (dataFileCategories != null) {
1✔
555
            ArrayList<String> ret = new ArrayList<>(dataFileCategories.size());
×
556
            for ( DataFileCategory dfc : dataFileCategories ) {
×
557
                ret.add( dfc.getName() );
×
558
            }
×
559
            return ret;
×
560
        } else {
561
            return new ArrayList<>();
1✔
562
        }
563
    }
564

565
    /* Only used with packageFiles after the implementation of multi-store in #6488
566
     * DO NOT USE THIS METHOD FOR ANY OTHER PURPOSES - it's @Deprecated for a reason.
567
     * 
568
     */
569
    @Deprecated 
570
    public Path getFileSystemDirectory() {
571
        Path studyDir = null;
×
572
        
573
        String filesRootDirectory = JvmSettings.FILES_DIRECTORY.lookup();
×
574
        
575
        if (this.getAlternativePersistentIndentifiers() != null && !this.getAlternativePersistentIndentifiers().isEmpty()) {
×
576
            for (AlternativePersistentIdentifier api : this.getAlternativePersistentIndentifiers()) {
×
577
                if (api.isStorageLocationDesignator()) {
×
578
                    studyDir = Paths.get(filesRootDirectory, api.getAuthority(), api.getIdentifier());
×
579
                    return studyDir;
×
580
                }
581
            }
×
582
        }
583

584
        if (this.getAuthority() != null && this.getIdentifier() != null) {
×
585
            studyDir = Paths.get(filesRootDirectory, this.getAuthority(), this.getIdentifier());
×
586
        }
587

588
        return studyDir;
×
589
    }
590
    
591
    public String getAlternativePersistentIdentifier(){
592
        String retVal = null;            
×
593
        if (this.getAlternativePersistentIndentifiers() != null && !this.getAlternativePersistentIndentifiers().isEmpty()) {
×
594
            for (AlternativePersistentIdentifier api : this.getAlternativePersistentIndentifiers()) {
×
595
                retVal = retVal != null ? retVal + "; " : "";
×
596
                retVal += api.getProtocol() + ":";
×
597
                retVal += api.getAuthority() + "/";
×
598
                retVal +=  api.getIdentifier();
×
599
            }
×
600
        }
601
        return retVal;       
×
602
    }
603
    
604
    public String getProtocolForFileStorage(){
605
        String retVal = getProtocol();            
×
606
        if (this.getAlternativePersistentIndentifiers() != null && !this.getAlternativePersistentIndentifiers().isEmpty()) {
×
607
            for (AlternativePersistentIdentifier altpid : this.getAlternativePersistentIndentifiers()) {
×
608
                if (altpid.isStorageLocationDesignator()) {
×
609
                    retVal = altpid.getProtocol();
×
610
                }
611
            }
×
612
        }
613
        return retVal;         
×
614
    }
615
    
616
    public String getAuthorityForFileStorage(){
617
        String retVal = getAuthority();            
1✔
618
        if (this.getAlternativePersistentIndentifiers() != null && !this.getAlternativePersistentIndentifiers().isEmpty()) {
1✔
619
            for (AlternativePersistentIdentifier altpid : this.getAlternativePersistentIndentifiers()) {
×
620
                if (altpid.isStorageLocationDesignator()) {
×
621
                    retVal = altpid.getAuthority();
×
622
                }
623
            }
×
624
        }
625
        return retVal;         
1✔
626
    }
627
    
628
    public String getIdentifierForFileStorage(){
629
        String retVal = getIdentifier();            
1✔
630
        if (this.getAlternativePersistentIndentifiers() != null && !this.getAlternativePersistentIndentifiers().isEmpty()) {
1✔
631
            for (AlternativePersistentIdentifier altpid : this.getAlternativePersistentIndentifiers()) {
×
632
                if (altpid.isStorageLocationDesignator()) {
×
633
                    retVal = altpid.getIdentifier();
×
634
                }
635
            }
×
636
        }
637
        return retVal;         
1✔
638
    }
639

640
    public String getNextMajorVersionString() {
641
        // Never need to get the next major version for harvested studies.
642
        if (isHarvested()) {
×
643
            throw new IllegalStateException();
×
644
        }
645
        for (DatasetVersion dv : this.getVersions()) {
×
646
            if (!dv.isWorkingCopy()) {
×
647
                return Integer.toString(dv.getVersionNumber().intValue() + 1) + ".0";
×
648
            }
649
        }
×
650
        return "1.0";
×
651
    }
652

653
    public String getNextMinorVersionString() {
654
        // Never need to get the next minor version for harvested studies.
655
        if (isHarvested()) {
×
656
            throw new IllegalStateException();
×
657
        }
658
        for (DatasetVersion dv : this.getVersions()) {
×
659
            if (!dv.isWorkingCopy()) {
×
660
                return Integer.toString(dv.getVersionNumber().intValue()) + "."
×
661
                        + Integer.toString(dv.getMinorVersionNumber().intValue() + 1);
×
662
            }
663
        }
×
664
        return "1.0";
×
665
    }
666

667
    public Integer getVersionNumber() {
668
        for (DatasetVersion dv : this.getVersions()) {
×
669
            if (!dv.isWorkingCopy()) {
×
670
                return dv.getVersionNumber().intValue();
×
671
            }
672
        }
×
673
        return 1;
×
674
    }
675

676
    public Integer getMinorVersionNumber() {
677
        for (DatasetVersion dv : this.getVersions()) {
×
678
            if (!dv.isWorkingCopy()) {
×
679
                return dv.getMinorVersionNumber().intValue();
×
680
            }
681
        }
×
682
        return 0;
×
683
    }
684

685
    public String getCitation() {
686
        return getCitation(false, getLatestVersion());
1✔
687
    }
688

689
    public String getCitation(DatasetVersion version) {
690
        return version.getCitation();
×
691
    }
692

693
    public String getCitation(boolean isOnlineVersion, DatasetVersion version) {
694
        return getCitation(isOnlineVersion, version, false);
1✔
695
    }
696
    
697
    public String getCitation(boolean isOnlineVersion, DatasetVersion version, boolean anonymized) {
698
        return version.getCitation(isOnlineVersion, anonymized);
1✔
699
    }
700

701
    public String getPublicationDateFormattedYYYYMMDD() {
702
        if (getPublicationDate() != null){
1✔
703
                   return new SimpleDateFormat("yyyy-MM-dd").format(getPublicationDate()); 
1✔
704
        }
705
        return null;
×
706
    }
707
    
708
    public Timestamp getCitationDate() {
709
        Timestamp citationDate = null;
1✔
710
        //Only calculate if this dataset doesn't use an alternate date field for publication date
711
        if (citationDateDatasetFieldType == null) {
1✔
712
            citationDate = super.getPublicationDate();
1✔
713
            if (embargoCitationDate != null) {
1✔
714
                if (citationDate.compareTo(embargoCitationDate) < 0) {
×
715
                    return embargoCitationDate;
×
716
                }
717
            }
718
        }
719
        return citationDate;
1✔
720
    }
721
    
722
    public String getCitationDateFormattedYYYYMMDD() {
723
        if (getCitationDate() != null){
×
724
                   return new SimpleDateFormat("yyyy-MM-dd").format(getCitationDate()); 
×
725
        }
726
        return null;
×
727
    }
728

729
    public DataFile getThumbnailFile() {
730
        return thumbnailFile;
1✔
731
    }
732

733
    public void setThumbnailFile(DataFile thumbnailFile) {
734
        this.thumbnailFile = thumbnailFile;
1✔
735
    }
1✔
736

737
    public boolean isUseGenericThumbnail() {
738
        return useGenericThumbnail;
1✔
739
    }
740

741
    public void setUseGenericThumbnail(boolean useGenericThumbnail) {
742
        this.useGenericThumbnail = useGenericThumbnail;
1✔
743
    }
1✔
744
    
745
    public List<DatasetMetrics> getDatasetMetrics() {
746
        return datasetMetrics;
×
747
    }
748

749
    public void setDatasetMetrics(List<DatasetMetrics> datasetMetrics) {
750
        this.datasetMetrics = datasetMetrics;
×
751
    }
×
752
    
753
    public List<DatasetExternalCitations> getDatasetExternalCitations() {
754
        return datasetExternalCitations;
×
755
    }
756

757
    public void setDatasetExternalCitations(List<DatasetExternalCitations> datasetExternalCitations) {
758
        this.datasetExternalCitations = datasetExternalCitations;
×
759
    }
×
760

761
    @ManyToOne
762
    @JoinColumn(name="harvestingClient_id")
763
    private  HarvestingClient harvestedFrom;
764

765
    public HarvestingClient getHarvestedFrom() {
766
        return this.harvestedFrom;
×
767
    }
768

769
    public void setHarvestedFrom(HarvestingClient harvestingClientConfig) {
770
        this.harvestedFrom = harvestingClientConfig;
1✔
771
    }
1✔
772
    
773
    public boolean isHarvested() {
774
        return this.harvestedFrom != null;
1✔
775
    }
776

777
    private String harvestIdentifier;
778
     
779
    public String getHarvestIdentifier() {
780
        return harvestIdentifier;
×
781
    }
782

783
    public void setHarvestIdentifier(String harvestIdentifier) {
784
        this.harvestIdentifier = harvestIdentifier;
×
785
    }
×
786

787
    public String getLocalURL() {
788
        //Assumes GlobalId != null
789
        return  SystemConfig.getDataverseSiteUrlStatic() + "/dataset.xhtml?persistentId=" + this.getGlobalId().asString();
×
790
    }
791
    
792
    public String getRemoteArchiveURL() {
793
        if (isHarvested()) {
×
794
            if (HarvestingClient.HARVEST_STYLE_DATAVERSE.equals(this.getHarvestedFrom().getHarvestStyle())) {
×
795
                return this.getHarvestedFrom().getArchiveUrl() + "/dataset.xhtml?persistentId=" + getGlobalId().asString();
×
796
            } else if (HarvestingClient.HARVEST_STYLE_VDC.equals(this.getHarvestedFrom().getHarvestStyle())) {
×
797
                String rootArchiveUrl = this.getHarvestedFrom().getHarvestingUrl();
×
798
                int c = rootArchiveUrl.indexOf("/OAIHandler");
×
799
                if (c > 0) {
×
800
                    rootArchiveUrl = rootArchiveUrl.substring(0, c);
×
801
                    return rootArchiveUrl + "/faces/study/StudyPage.xhtml?globalId=" + getGlobalId().asString();
×
802
                }
803
            } else if (HarvestingClient.HARVEST_STYLE_ICPSR.equals(this.getHarvestedFrom().getHarvestStyle())) {
×
804
                // For the ICPSR, it turns out that the best thing to do is to 
805
                // rely on the DOI to send the user to the right landing page for 
806
                // the study: 
807
                //String icpsrId = identifier;
808
                //return this.getOwner().getHarvestingClient().getArchiveUrl() + "/icpsrweb/ICPSR/studies/"+icpsrId+"?q="+icpsrId+"&amp;searchSource=icpsr-landing";
809
                return "http://doi.org/" + this.getAuthority() + "/" + this.getIdentifier();
×
810
            } else if (HarvestingClient.HARVEST_STYLE_NESSTAR.equals(this.getHarvestedFrom().getHarvestStyle())) {
×
811
                String nServerURL = this.getHarvestedFrom().getArchiveUrl();
×
812
                // chop any trailing slashes in the server URL - or they will result
813
                // in multiple slashes in the final URL pointing to the study 
814
                // on server of origin; Nesstar doesn't like it, apparently. 
815
                nServerURL = nServerURL.replaceAll("/*$", "");
×
816

817
                String nServerURLencoded = nServerURL;
×
818

819
                nServerURLencoded = nServerURLencoded.replace(":", "%3A").replace("/", "%2F");
×
820
                //SEK 09/13/18
821
                String NesstarWebviewPage = nServerURL
×
822
                        + "/webview/?mode=documentation&submode=abstract&studydoc="
823
                        + nServerURLencoded + "%2Fobj%2FfStudy%2F"
824
                        + this.getIdentifier()
×
825
                        + "&top=yes";
826

827
                return NesstarWebviewPage;
×
828
            } else if (HarvestingClient.HARVEST_STYLE_ROPER.equals(this.getHarvestedFrom().getHarvestStyle())) {
×
829
                return this.getHarvestedFrom().getArchiveUrl() + "/CFIDE/cf/action/catalog/abstract.cfm?archno=" + this.getIdentifier();
×
830
            } else if (HarvestingClient.HARVEST_STYLE_HGL.equals(this.getHarvestedFrom().getHarvestStyle())) {
×
831
                // a bit of a hack, true. 
832
                // HGL documents, when turned into Dataverse studies/datasets
833
                // all 1 datafile; the location ("storage identifier") of the file
834
                // is the URL pointing back to the HGL GUI viewer. This is what 
835
                // we will display for the dataset URL.  -- L.A. 
836
                // TODO: create a 4.+ ticket for a cleaner solution. 
837
                List<DataFile> dataFiles = this.getFiles();
×
838
                if (dataFiles != null && dataFiles.size() == 1) {
×
839
                    if (dataFiles.get(0) != null) {
×
840
                        String hglUrl = dataFiles.get(0).getStorageIdentifier();
×
841
                        if (hglUrl != null && hglUrl.matches("^http.*")) {
×
842
                            return hglUrl;
×
843
                        }
844
                    }
845
                }
846
                return this.getHarvestedFrom().getArchiveUrl();
×
847
            } else if (HarvestingClient.HARVEST_STYLE_DEFAULT.equals(this.getHarvestedFrom().getHarvestStyle())) {
×
848
                // This is a generic OAI archive. 
849
                // The metadata we harvested for this dataset is most likely a 
850
                // simple DC record that does not contain a URL pointing back at 
851
                // the specific location on the source archive. But, it probably
852
                // has a global identifier, a DOI or a Handle - so we should be 
853
                // able to redirect to the proper global resolver. 
854
                // But since this is a harvested dataset, we will assume that 
855
                // there is a possibility tha this object does NOT have all the 
856
                // valid persistent identifier components.
857
                
858
                if (StringUtil.nonEmpty(this.getProtocol()) 
×
859
                        && StringUtil.nonEmpty(this.getAuthority())
×
860
                        && StringUtil.nonEmpty(this.getIdentifier())) {
×
861
                    
862
                    // If there is a custom archival url for this Harvesting 
863
                    // Source, we'll use that
864
                    String harvestingUrl = this.getHarvestedFrom().getHarvestingUrl();
×
865
                    String archivalUrl = this.getHarvestedFrom().getArchiveUrl();
×
866
                    if (!harvestingUrl.contains(archivalUrl)) {
×
867
                        // When a Harvesting Client is created, the “archive url” is set to 
868
                        // just the host part of the OAI url automatically. 
869
                        // For example, if the OAI url was "https://remote.edu/oai", 
870
                        // the archive url will default to "https://remote.edu/". 
871
                        // If this is no longer true, we know it means the admin 
872
                        // went to the trouble of setting it to something else - 
873
                        // so we should use this url for the redirects back to source, 
874
                        // instead of the global id resolver.
875
                        return archivalUrl + this.getAuthority() + "/" + this.getIdentifier();
×
876
                    }
877
                    // ... if not, we'll redirect to the resolver for the global id: 
878
                    return this.getPersistentURL();    
×
879
                }
880
                
881
                // All we can do is redirect them to the top-level URL we have 
882
                // on file for this remote archive:
883
                return this.getHarvestedFrom().getArchiveUrl();
×
884
            } else {
885
                // This is really not supposed to happen - this is a harvested
886
                // dataset for which we don't have ANY information on the nature
887
                // of the archive we got it from. So all we can do is redirect 
888
                // the user to the top-level URL we have on file for this remote 
889
                // archive:
890
                return this.getHarvestedFrom().getArchiveUrl();
×
891
            }
892
        }
893

894
        return null;
×
895
    }
896

897
    public String getHarvestingDescription() {
898
        if (isHarvested()) {
×
899
            return this.getHarvestedFrom().getArchiveDescription();
×
900
        }
901

902
        return null;
×
903
    }
904

905
    public boolean hasEnabledGuestbook(){
906
        Guestbook gb = this.getGuestbook();
×
907

908
        return ( gb != null && gb.isEnabled());
×
909
    }
910
    
911
    @Override
912
    public boolean equals(Object object) {
913
        // TODO: Warning - this method won't work in the case the id fields are not set
914
        if (!(object instanceof Dataset)) {
1✔
915
            return false;
×
916
        }
917
        Dataset other = (Dataset) object;
1✔
918
        return Objects.equals(getId(), other.getId());
1✔
919
    }
920
    
921
    @Override
922
    public int hashCode() {
923
        return Objects.hash(getId());
1✔
924
    }
925
    
926
    @Override
927
    public <T> T accept(Visitor<T> v) {
928
        return v.visit(this);
×
929
    }
930

931
    @Override
932
    public String getDisplayName() {
933
        DatasetVersion dsv = getReleasedVersion();
×
934
        String result = dsv != null ? dsv.getTitle() : getLatestVersion().getTitle();
×
935
        boolean resultIsEmpty = result == null || "".equals(result);
×
936
        if (resultIsEmpty && getGlobalId() != null) {
×
937
            return getGlobalId().asString();
×
938
        }
939
        return result;
×
940
    }
941
    
942
    @Override
943
    public String getCurrentName(){
944
        return getLatestVersion().getTitle();
×
945
    }
946

947
    @Override
948
    protected boolean isPermissionRoot() {
949
        return false;
×
950
    }
951
    
952
    @Override
953
    public boolean isAncestorOf( DvObject other ) {
954
        return equals(other) || equals(other.getOwner());
×
955
    }
956

957
    public DatasetThumbnail getDatasetThumbnail(int size) {
958
        return DatasetUtil.getThumbnail(this, size);
1✔
959
    }
960
    
961
    /** 
962
     * Handle the case where we also have the datasetVersionId.
963
     * This saves trying to find the latestDatasetVersion, and 
964
     * other costly queries, etc.
965
     * 
966
     * @param datasetVersion
967
     * @return A thumbnail of the dataset (may be {@code null}).
968
     */
969
    public DatasetThumbnail getDatasetThumbnail(DatasetVersion datasetVersion, int size) {
970
        return DatasetUtil.getThumbnail(this, datasetVersion, size);
×
971
    }
972

973
    @Override
974
    public String getTargetUrl() {
975
        return Dataset.TARGET_URL;
×
976
    }
977
}
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