comparison src/main/java/edu/harvard/iq/dataverse/Dataset.java @ 10:a50cf11e5178

Rewrite LGDataverse completely upgrading to dataverse4.0
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Tue, 08 Sep 2015 17:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
9:5926d6419569 10:a50cf11e5178
1 package edu.harvard.iq.dataverse;
2
3 import java.nio.file.Path;
4 import java.nio.file.Paths;
5 import java.text.SimpleDateFormat;
6 import java.util.ArrayList;
7 import java.util.Collection;
8 import java.util.Date;
9 import java.util.List;
10 import java.util.Objects;
11 import javax.persistence.CascadeType;
12 import javax.persistence.Column;
13 import javax.persistence.Entity;
14 import javax.persistence.Index;
15 import javax.persistence.JoinColumn;
16 import javax.persistence.NamedQueries;
17 import javax.persistence.NamedQuery;
18 import javax.persistence.OneToMany;
19 import javax.persistence.OneToOne;
20 import javax.persistence.OrderBy;
21 import javax.persistence.Table;
22 import javax.persistence.Temporal;
23 import javax.persistence.TemporalType;
24 import javax.persistence.UniqueConstraint;
25 import org.hibernate.validator.constraints.NotBlank;
26
27 /**
28 *
29 * @author skraffmiller
30 */
31 @NamedQueries(
32 @NamedQuery(name = "Dataset.findByIdentifier",
33 query = "SELECT d FROM Dataset d WHERE d.identifier=:identifier")
34 )
35 @Entity
36 @Table(indexes = {
37 @Index(columnList = "guestbook_id"),
38 @Index(columnList = "thumbnailfile_id")},
39 uniqueConstraints = @UniqueConstraint(columnNames = {"authority,protocol,identifier,doiseparator"}))
40 public class Dataset extends DvObjectContainer {
41
42 private static final long serialVersionUID = 1L;
43
44 @OneToMany(mappedBy = "owner", cascade = CascadeType.MERGE)
45 private List<DataFile> files = new ArrayList();
46
47 private String protocol;
48 private String authority;
49 private String doiSeparator;
50
51 @Temporal(value = TemporalType.TIMESTAMP)
52 private Date globalIdCreateTime;
53
54 @NotBlank(message = "Please enter an identifier for your dataset.")
55 @Column(nullable = false)
56 private String identifier;
57 @OneToMany(mappedBy = "dataset", orphanRemoval = true, cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
58 @OrderBy("versionNumber DESC, minorVersionNumber DESC")
59 private List<DatasetVersion> versions = new ArrayList();
60 @OneToOne(mappedBy = "dataset", cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
61 private DatasetLock datasetLock;
62 @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
63 @JoinColumn(name = "thumbnailfile_id")
64 private DataFile thumbnailFile;
65
66 @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
67 @JoinColumn(name = "guestbook_id", unique = false, nullable = true, insertable = true, updatable = true)
68 private Guestbook guestbook;
69
70 @OneToMany(mappedBy="dataset", cascade={CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
71 private List<DatasetLinkingDataverse> datasetLinkingDataverses;
72
73 public List<DatasetLinkingDataverse> getDatasetLinkingDataverses() {
74 return datasetLinkingDataverses;
75 }
76
77 public void setDatasetLinkingDataverses(List<DatasetLinkingDataverse> datasetLinkingDataverses) {
78 this.datasetLinkingDataverses = datasetLinkingDataverses;
79 }
80
81 private boolean fileAccessRequest;
82 @OneToMany(mappedBy = "dataset", orphanRemoval = true, cascade = {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST})
83 private List<DataFileCategory> dataFileCategories = null;
84
85 public Dataset() {
86 //this.versions = new ArrayList();
87 DatasetVersion datasetVersion = new DatasetVersion();
88 datasetVersion.setDataset(this);
89 datasetVersion.setVersionState(DatasetVersion.VersionState.DRAFT);
90 datasetVersion.setFileMetadatas(new ArrayList());
91 datasetVersion.setVersionNumber(new Long(1));
92 datasetVersion.setMinorVersionNumber(new Long(0));
93 versions.add(datasetVersion);
94 }
95
96 public String getProtocol() {
97 return protocol;
98 }
99
100 public void setProtocol(String protocol) {
101 this.protocol = protocol;
102 }
103
104 public String getAuthority() {
105 return authority;
106 }
107
108 public void setAuthority(String authority) {
109 this.authority = authority;
110 }
111
112 public String getIdentifier() {
113 return identifier;
114 }
115
116 public void setIdentifier(String identifier) {
117 this.identifier = identifier;
118 }
119
120 public String getDoiSeparator() {
121 return doiSeparator;
122 }
123
124 public void setDoiSeparator(String doiSeparator) {
125 this.doiSeparator = doiSeparator;
126 }
127
128 public Date getGlobalIdCreateTime() {
129 return globalIdCreateTime;
130 }
131
132 public void setGlobalIdCreateTime(Date globalIdCreateTime) {
133 this.globalIdCreateTime = globalIdCreateTime;
134 }
135
136 public Guestbook getGuestbook() {
137 return guestbook;
138 }
139
140 public void setGuestbook(Guestbook guestbook) {
141 this.guestbook = guestbook;
142 }
143
144 public boolean isFileAccessRequest() {
145 return fileAccessRequest;
146 }
147
148 public void setFileAccessRequest(boolean fileAccessRequest) {
149 this.fileAccessRequest = fileAccessRequest;
150 }
151
152 public String getPersistentURL() {
153 switch (this.getProtocol()) {
154 case "hdl":
155 return getHandleURL();
156 case "doi":
157 return getEZIdURL();
158 default:
159 return "";
160 }
161 }
162
163 private String getHandleURL() {
164 return "http://hdl.handle.net/" + authority + "/" + getIdentifier();
165 }
166
167 private String getEZIdURL() {
168 if (globalIdCreateTime != null) {
169 return "http://dx.doi.org/" + authority + doiSeparator + getIdentifier();
170 } else {
171 return "http://dx.doi.org/" + authority + doiSeparator + "Dataset-not-registered";
172 }
173 }
174
175 public String getGlobalId() {
176
177 return protocol + ":" + authority + doiSeparator + getIdentifier();
178
179 }
180
181 public List<DataFile> getFiles() {
182 return files;
183 }
184
185 public void setFiles(List<DataFile> files) {
186 this.files = files;
187 }
188
189 public DatasetLock getDatasetLock() {
190 return datasetLock;
191 }
192
193 public void setDatasetLock(DatasetLock datasetLock) {
194 this.datasetLock = datasetLock;
195 }
196
197 public boolean isLocked() {
198 if (datasetLock != null) {
199 return true;
200 }
201 return false;
202 }
203
204 public boolean isDeaccessioned() {
205 // return true, if all published versions were deaccessioned
206 boolean hasDeaccessionedVersions = false;
207 for (DatasetVersion testDsv : getVersions()) {
208 if (testDsv.isReleased()) {
209 return false;
210 }
211 if (testDsv.isDeaccessioned()) {
212 hasDeaccessionedVersions = true;
213 }
214 }
215 return hasDeaccessionedVersions; // since any published version would have already returned
216 }
217
218 public DatasetVersion getLatestVersion() {
219 return getVersions().get(0);
220 }
221
222 public DatasetVersion getLatestVersionForCopy() {
223 for (DatasetVersion testDsv : getVersions()) {
224 if (testDsv.isReleased() || testDsv.isArchived()) {
225 return testDsv;
226 }
227 }
228 return getVersions().get(0);
229 }
230
231 public List<DatasetVersion> getVersions() {
232 return versions;
233 }
234
235 public void setVersions(List<DatasetVersion> versions) {
236 this.versions = versions;
237 }
238
239 private DatasetVersion createNewDatasetVersion(Template template) {
240 DatasetVersion dsv = new DatasetVersion();
241 dsv.setVersionState(DatasetVersion.VersionState.DRAFT);
242 dsv.setFileMetadatas(new ArrayList());
243 DatasetVersion latestVersion = null;
244
245 //if the latest version has values get them copied over
246 if (!(template == null)) {
247 if (!template.getDatasetFields().isEmpty()) {
248 dsv.setDatasetFields(dsv.copyDatasetFields(template.getDatasetFields()));
249 }
250 dsv.setLicense(DatasetVersion.License.CC0);
251 } else {
252 latestVersion = getLatestVersionForCopy();
253 if (latestVersion.getDatasetFields() != null && !latestVersion.getDatasetFields().isEmpty()) {
254 dsv.setDatasetFields(dsv.copyDatasetFields(latestVersion.getDatasetFields()));
255 }
256 dsv.setFileAccessRequest(latestVersion.isFileAccessRequest());
257 dsv.setTermsOfUse(latestVersion.getTermsOfUse());
258 dsv.setTermsOfAccess(latestVersion.getTermsOfAccess());
259 dsv.setConfidentialityDeclaration(latestVersion.getConfidentialityDeclaration());
260 dsv.setSpecialPermissions(latestVersion.getSpecialPermissions());
261 dsv.setRestrictions(latestVersion.getRestrictions());
262 dsv.setCitationRequirements(latestVersion.getCitationRequirements());
263 dsv.setDepositorRequirements(latestVersion.getDepositorRequirements());
264 dsv.setConditions(latestVersion.getConditions());
265 dsv.setDisclaimer(latestVersion.getDisclaimer());
266 dsv.setDataAccessPlace(latestVersion.getDataAccessPlace());
267 dsv.setOriginalArchive(latestVersion.getOriginalArchive());
268 dsv.setAvailabilityStatus(latestVersion.getAvailabilityStatus());
269 dsv.setContactForAccess(latestVersion.getContactForAccess());
270 dsv.setSizeOfCollection(latestVersion.getSizeOfCollection());
271 dsv.setStudyCompletion(latestVersion.getStudyCompletion());
272
273 for (FileMetadata fm : latestVersion.getFileMetadatas()) {
274 FileMetadata newFm = new FileMetadata();
275 // TODO:
276 // the "category" will be removed, shortly.
277 // (replaced by multiple, tag-like categories of
278 // type DataFileCategory) -- L.A. beta 10
279 //newFm.setCategory(fm.getCategory());
280 // yep, these are the new categories:
281 newFm.setCategories(fm.getCategories());
282 newFm.setDescription(fm.getDescription());
283 newFm.setLabel(fm.getLabel());
284 newFm.setRestricted(fm.isRestricted());
285 newFm.setDataFile(fm.getDataFile());
286 newFm.setDatasetVersion(dsv);
287 dsv.getFileMetadatas().add(newFm);
288 }
289 dsv.setLicense(latestVersion.getLicense());
290 }
291
292 // I'm adding the version to the list so it will be persisted when
293 // the study object is persisted.
294 if (template == null) {
295 getVersions().add(0, dsv);
296 } else {
297 this.setVersions(new ArrayList());
298 getVersions().add(0, dsv);
299 }
300
301 dsv.setDataset(this);
302 return dsv;
303 }
304
305 public DatasetVersion getEditVersion() {
306 return getEditVersion(null);
307 }
308
309 public DatasetVersion getEditVersion(Template template) {
310 DatasetVersion latestVersion = this.getLatestVersion();
311 if (!latestVersion.isWorkingCopy() || template != null) {
312 // if the latest version is released or archived, create a new version for editing
313 return createNewDatasetVersion(template);
314 } else {
315 // else, edit existing working copy
316 return latestVersion;
317 }
318 }
319
320 public DatasetVersion getCreateVersion() {
321 DatasetVersion dsv = new DatasetVersion();
322 dsv.setVersionState(DatasetVersion.VersionState.DRAFT);
323 dsv.setDataset(this);
324 dsv.setDatasetFields(dsv.initDatasetFields());;
325 dsv.setFileMetadatas(new ArrayList());
326
327 this.setVersions(new ArrayList());
328 getVersions().add(0, dsv);
329
330 return dsv;
331 }
332
333 public Date getMostRecentMajorVersionReleaseDate() {
334 if (this.isHarvested()) {
335 return getVersions().get(0).getReleaseTime();
336 } else {
337 for (DatasetVersion version : this.getVersions()) {
338 if (version.isReleased() && version.getMinorVersionNumber().equals(new Long(0))) {
339 return version.getReleaseTime();
340 }
341 }
342 return null;
343 }
344 }
345
346 public DatasetVersion getReleasedVersion() {
347 for (DatasetVersion version : this.getVersions()) {
348 if (version.isReleased()) {
349 return version;
350 }
351 }
352 return null;
353 }
354
355 public List<DataFileCategory> getCategories() {
356 return dataFileCategories;
357 }
358
359 public void setFileCategories(List<DataFileCategory> categories) {
360 this.dataFileCategories = categories;
361 }
362
363 public void addFileCategory(DataFileCategory category) {
364 if (dataFileCategories == null) {
365 dataFileCategories = new ArrayList<>();
366 }
367 dataFileCategories.add(category);
368 }
369
370 public Collection<String> getCategoriesByName() {
371 Collection<String> ret = getCategoryNames();
372
373 // "Documentation", "Data" and "Code" are the 3 default categories that we
374 // present by default:
375 // (TODO: ? - provide these as constants somewhere? -- L.A. beta15)
376 if (!ret.contains("Documentation")) {
377 ret.add("Documentation");
378 }
379 if (!ret.contains("Data")) {
380 ret.add("Data");
381 }
382 if (!ret.contains("Code")) {
383 ret.add("Code");
384 }
385
386 return ret;
387 }
388
389 public void setCategoriesByName(List<String> newCategoryNames) {
390 if (newCategoryNames != null) {
391 Collection<String> oldCategoryNames = getCategoryNames();
392
393 for (int i = 0; i < newCategoryNames.size(); i++) {
394 if (!oldCategoryNames.contains(newCategoryNames.get(i))) {
395 DataFileCategory newCategory = new DataFileCategory();
396 newCategory.setName(newCategoryNames.get(i));
397 newCategory.setDataset(this);
398 this.addFileCategory(newCategory);
399 }
400 }
401 }
402 }
403 /*
404 public void addCategoryByName(String newCategoryName) {
405 if (newCategoryName != null && !newCategoryName.equals("")) {
406 Collection<String> oldCategoryNames = getCategoryNames();
407 if (!oldCategoryNames.contains(newCategoryName)) {
408 DataFileCategory newCategory = new DataFileCategory();
409 newCategory.setName(newCategoryName);
410 newCategory.setDataset(this);
411 this.addFileCategory(newCategory);
412 }
413 }
414 }*/
415
416 public DataFileCategory getCategoryByName(String categoryName) {
417 if (categoryName != null && !categoryName.equals("")) {
418 if (dataFileCategories != null) {
419 for (int i = 0; i < dataFileCategories.size(); i++) {
420 if (categoryName.equals(dataFileCategories.get(i).getName())) {
421 return dataFileCategories.get(i);
422 }
423 }
424 }
425
426 DataFileCategory newCategory = new DataFileCategory();
427 newCategory.setName(categoryName);
428 newCategory.setDataset(this);
429 this.addFileCategory(newCategory);
430
431 return newCategory;
432 }
433 return null;
434 }
435
436 private Collection<String> getCategoryNames() {
437 ArrayList<String> ret = new ArrayList<>();
438 if (dataFileCategories != null) {
439 for (int i = 0; i < dataFileCategories.size(); i++) {
440 ret.add(dataFileCategories.get(i).getName());
441 }
442 }
443 return ret;
444 }
445
446 public Path getFileSystemDirectory() {
447 Path studyDir = null;
448
449 String filesRootDirectory = System.getProperty("dataverse.files.directory");
450 if (filesRootDirectory == null || filesRootDirectory.equals("")) {
451 filesRootDirectory = "/tmp/files";
452 }
453
454 if (this.getAuthority() != null && this.getIdentifier() != null) {
455 studyDir = Paths.get(filesRootDirectory, this.getAuthority(), this.getIdentifier());
456 }
457
458 return studyDir;
459 }
460
461 public String getNextMajorVersionString() {
462 // Never need to get the next major version for harvested studies.
463 if (isHarvested()) {
464 throw new IllegalStateException();
465 }
466 for (DatasetVersion dv : this.getVersions()) {
467 if (!dv.isWorkingCopy()) {
468 return Integer.toString(dv.getVersionNumber().intValue() + 1) + ".0";
469 }
470 }
471 return "1.0";
472 }
473
474 public String getNextMinorVersionString() {
475 // Never need to get the next minor version for harvested studies.
476 if (isHarvested()) {
477 throw new IllegalStateException();
478 }
479 for (DatasetVersion dv : this.getVersions()) {
480 if (!dv.isWorkingCopy()) {
481 return Integer.toString(dv.getVersionNumber().intValue()) + "."
482 + Integer.toString(dv.getMinorVersionNumber().intValue() + 1);
483 }
484 }
485 return "1.0";
486 }
487
488 public Integer getVersionNumber() {
489 for (DatasetVersion dv : this.getVersions()) {
490 if (!dv.isWorkingCopy()) {
491 return dv.getVersionNumber().intValue();
492 }
493 }
494 return 1;
495 }
496
497 public Integer getMinorVersionNumber() {
498 for (DatasetVersion dv : this.getVersions()) {
499 if (!dv.isWorkingCopy()) {
500 return dv.getMinorVersionNumber().intValue();
501 }
502 }
503 return 0;
504 }
505
506 public String getCitation() {
507 return getCitation(false, getLatestVersion());
508 }
509
510 public String getCitation(DatasetVersion version) {
511 return version.getCitation();
512 }
513
514 public String getCitation(boolean isOnlineVersion, DatasetVersion version) {
515 return version.getCitation(isOnlineVersion);
516 }
517
518 public String getPublicationDateFormattedYYYYMMDD() {
519 return new SimpleDateFormat("yyyy-MM-dd").format(getPublicationDate());
520 }
521
522 public DataFile getThumbnailFile() {
523 return thumbnailFile;
524 }
525
526 public void setThumbnailFile(DataFile thumbnailFile) {
527 this.thumbnailFile = thumbnailFile;
528 }
529
530 public boolean isHarvested() {
531 // TODO:
532 // eventually, this will be more complex:
533 // A dataverse owner will be able to harvest some datasets into
534 // any dataverse, in addition to any local datasets there.
535 // -- L.A. 4.0
536 Dataverse ownerDataverse = this.getOwner();
537 if (ownerDataverse != null) {
538 return ownerDataverse.isHarvested();
539 }
540 return false;
541 }
542
543 public String getRemoteArchiveURL() {
544 if (isHarvested()) {
545 if (HarvestingDataverseConfig.HARVEST_STYLE_DATAVERSE.equals(this.getOwner().getHarvestingDataverseConfig().getHarvestStyle())) {
546 return this.getOwner().getHarvestingDataverseConfig().getArchiveUrl() + "/dataset.xhtml?persistentId=" + getGlobalId();
547 } else if (HarvestingDataverseConfig.HARVEST_STYLE_VDC.equals(this.getOwner().getHarvestingDataverseConfig().getHarvestStyle())) {
548 String rootArchiveUrl = this.getOwner().getHarvestingDataverseConfig().getHarvestingUrl();
549 int c = rootArchiveUrl.indexOf("/OAIHandler");
550 if (c > 0) {
551 rootArchiveUrl = rootArchiveUrl.substring(0, c);
552 return rootArchiveUrl + "/faces/study/StudyPage.xhtml?globalId=" + getGlobalId();
553 }
554 } else if (HarvestingDataverseConfig.HARVEST_STYLE_ICPSR.equals(this.getOwner().getHarvestingDataverseConfig().getHarvestStyle())) {
555 // For the ICPSR, it turns out that the best thing to do is to
556 // rely on the DOI to send the user to the right landing page for
557 // the study:
558 //String icpsrId = identifier;
559 //return this.getOwner().getHarvestingDataverseConfig().getArchiveUrl() + "/icpsrweb/ICPSR/studies/"+icpsrId+"?q="+icpsrId+"&amp;searchSource=icpsr-landing";
560 return "http://doi.org/" + authority + "/" + identifier;
561 } else if (HarvestingDataverseConfig.HARVEST_STYLE_NESSTAR.equals(this.getOwner().getHarvestingDataverseConfig().getHarvestStyle())) {
562 String nServerURL = this.getOwner().getHarvestingDataverseConfig().getArchiveUrl();
563 // chop any trailing slashes in the server URL - or they will result
564 // in multiple slashes in the final URL pointing to the study
565 // on server of origin; Nesstar doesn't like it, apparently.
566 nServerURL = nServerURL.replaceAll("/*$", "");
567
568 String nServerURLencoded = nServerURL;
569
570 nServerURLencoded.replace(":", "%3A");
571 nServerURLencoded.replace("/", "%2F");
572
573 String NesstarWebviewPage = nServerURL
574 + "/webview/?mode=documentation&submode=abstract&studydoc="
575 + nServerURLencoded + "%2Fobj%2FfStudy%2F"
576 + identifier
577 + "&top=yes";
578
579 return NesstarWebviewPage;
580 } else if (HarvestingDataverseConfig.HARVEST_STYLE_ROPER.equals(this.getOwner().getHarvestingDataverseConfig().getHarvestStyle())) {
581 return this.getOwner().getHarvestingDataverseConfig().getArchiveUrl() + "/CFIDE/cf/action/catalog/abstract.cfm?archno=" + identifier;
582 } else if (HarvestingDataverseConfig.HARVEST_STYLE_HGL.equals(this.getOwner().getHarvestingDataverseConfig().getHarvestStyle())) {
583 // a bit of a hack, true.
584 // TODO: create a 4.+ ticket for a cleaner solution.
585 List<DataFile> dataFiles = this.getFiles();
586 if (dataFiles != null && dataFiles.size() == 1) {
587 if (dataFiles.get(0) != null) {
588 String hglUrl = dataFiles.get(0).getFileSystemName();
589 if (hglUrl != null && hglUrl.matches("^http.*")) {
590 return hglUrl;
591 }
592 }
593 }
594 return this.getOwner().getHarvestingDataverseConfig().getArchiveUrl();
595 }else {
596 return this.getOwner().getHarvestingDataverseConfig().getArchiveUrl();
597 }
598 }
599
600 return null;
601 }
602
603 public String getHarvestingDescription() {
604 if (isHarvested()) {
605 return this.getOwner().getHarvestingDataverseConfig().getArchiveDescription();
606 }
607
608 return null;
609 }
610
611 @Override
612 public boolean equals(Object object) {
613 // TODO: Warning - this method won't work in the case the id fields are not set
614 if (!(object instanceof Dataset)) {
615 return false;
616 }
617 Dataset other = (Dataset) object;
618 return Objects.equals(getId(), other.getId());
619 }
620
621 @Override
622 public <T> T accept(Visitor<T> v) {
623 return v.visit(this);
624 }
625
626 @Override
627 public String getDisplayName() {
628 DatasetVersion dsv = getReleasedVersion();
629 return dsv != null ? dsv.getTitle() : getLatestVersion().getTitle();
630 }
631
632 @Override
633 protected boolean isPermissionRoot() {
634 return false;
635 }
636
637 }