diff --git a/src/main/java/Bundle.properties b/src/main/java/Bundle.properties
index d9b8ce2ecc2..51c80a47c35 100755
--- a/src/main/java/Bundle.properties
+++ b/src/main/java/Bundle.properties
@@ -1490,6 +1490,7 @@ file.lastupdated.label=Last Updated
file.metadataTab.fileMetadata.header=File Metadata
file.metadataTab.fileMetadata.persistentid.label=Data File Persistent ID
+file.metadataTab.fileMetadata.downloadUrl.label=Download URL
file.metadataTab.fileMetadata.unf.label=UNF
file.metadataTab.fileMetadata.size.label=Size
file.metadataTab.fileMetadata.type.label=Type
diff --git a/src/main/java/edu/harvard/iq/dataverse/Dataset.java b/src/main/java/edu/harvard/iq/dataverse/Dataset.java
index 5b0dc443942..678ecd6f2fb 100644
--- a/src/main/java/edu/harvard/iq/dataverse/Dataset.java
+++ b/src/main/java/edu/harvard/iq/dataverse/Dataset.java
@@ -328,10 +328,14 @@ public DatasetVersion getEditVersion(Template template) {
}
}
- public DatasetVersion getCreateVersion() {
+ /**
+ * @todo Investigate if this method should be deprecated in favor of
+ * createNewDatasetVersion.
+ */
+ public DatasetVersion getCreateVersion() {
DatasetVersion dsv = new DatasetVersion();
dsv.setVersionState(DatasetVersion.VersionState.DRAFT);
- dsv.setDataset(this);
+ dsv.setDataset(this);
dsv.initDefaultValues();
this.setVersions(new ArrayList());
getVersions().add(0, dsv);
diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
index 4662c797a1c..12482c54b2a 100644
--- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
+++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
@@ -3311,7 +3311,7 @@ public boolean isFileAccessRequestMultiSignUpButtonEnabled(){
}
public boolean isDownloadPopupRequired() {
- return fileDownloadService.isDownloadPopupRequired(workingVersion);
+ return FileUtil.isDownloadPopupRequired(workingVersion);
}
public String requestAccessMultipleFiles(String fileIdString) {
diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java
index 437c42ba8b3..8e091420428 100644
--- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java
+++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java
@@ -131,6 +131,11 @@ public void setVersion(Long version) {
@Column(length = VERSION_NOTE_MAX_LENGTH)
private String versionNote;
+ /**
+ * @todo versionState should never be null so when we are ready, uncomment
+ * the `nullable = false` below.
+ */
+// @Column(nullable = false)
@Enumerated(EnumType.STRING)
private VersionState versionState;
diff --git a/src/main/java/edu/harvard/iq/dataverse/FileDownloadServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/FileDownloadServiceBean.java
index c78445d61aa..2de075eb835 100644
--- a/src/main/java/edu/harvard/iq/dataverse/FileDownloadServiceBean.java
+++ b/src/main/java/edu/harvard/iq/dataverse/FileDownloadServiceBean.java
@@ -120,42 +120,15 @@ public void callDownloadServlet(String multiFileString, Boolean gbRecordsWritten
//return fileDownloadUrl;
}
-
- //private String callDownloadServlet( String downloadType, Long fileId){
- public void callDownloadServlet( String downloadType, Long fileId, Boolean gbRecordsWritten){
-
- String fileDownloadUrl = "/api/access/datafile/" + fileId;
-
- if (downloadType != null && downloadType.equals("bundle")){
- fileDownloadUrl = "/api/access/datafile/bundle/" + fileId;
- }
- if (downloadType != null && downloadType.equals("original")){
- fileDownloadUrl = "/api/access/datafile/" + fileId + "?format=original";
- }
- if (downloadType != null && downloadType.equals("RData")){
- fileDownloadUrl = "/api/access/datafile/" + fileId + "?format=RData";
- }
- if (downloadType != null && downloadType.equals("var")){
- fileDownloadUrl = "/api/meta/datafile/" + fileId;
- }
- if (downloadType != null && downloadType.equals("tab")){
- fileDownloadUrl = "/api/access/datafile/" + fileId+ "?format=tab";
- }
- if (gbRecordsWritten){
- if(downloadType != null && ( downloadType.equals("original") || downloadType.equals("RData") || downloadType.equals("tab")) ){
- fileDownloadUrl += "&gbrecs=true";
- } else {
- fileDownloadUrl += "?gbrecs=true";
- }
-
- }
- logger.fine("Returning file download url: " + fileDownloadUrl);
+
+ public void callDownloadServlet(String downloadType, Long fileId, boolean gbRecordsWritten) {
+ String fileDownloadUrl = FileUtil.getFileDownloadUrlPath(downloadType, fileId, gbRecordsWritten);
+ logger.fine("Redirecting to file download url: " + fileDownloadUrl);
try {
FacesContext.getCurrentInstance().getExternalContext().redirect(fileDownloadUrl);
} catch (IOException ex) {
- logger.info("Failed to issue a redirect to file download url.");
+ logger.info("Failed to issue a redirect to file download url (" + fileDownloadUrl + "): " + ex);
}
- //return fileDownloadUrl;
}
//public String startFileDownload(FileMetadata fileMetadata, String format) {
@@ -229,39 +202,7 @@ public String startWorldMapDownloadLink(GuestbookResponse guestbookResponse, Fil
}
return retVal;
}
-
- public boolean isDownloadPopupRequired(DatasetVersion datasetVersion) {
- // Each of these conditions is sufficient reason to have to
- // present the user with the popup:
- if (datasetVersion == null){
- return false;
- }
- //0. if version is draft then Popup "not required"
- if (!datasetVersion.isReleased()){
- return false;
- }
- // 1. License and Terms of Use:
- if (datasetVersion.getTermsOfUseAndAccess() != null) {
- if (!TermsOfUseAndAccess.License.CC0.equals(datasetVersion.getTermsOfUseAndAccess().getLicense())
- && !(datasetVersion.getTermsOfUseAndAccess().getTermsOfUse() == null
- || datasetVersion.getTermsOfUseAndAccess().getTermsOfUse().equals(""))) {
- return true;
- }
-
- // 2. Terms of Access:
- if (!(datasetVersion.getTermsOfUseAndAccess().getTermsOfAccess() == null) && !datasetVersion.getTermsOfUseAndAccess().getTermsOfAccess().equals("")) {
- return true;
- }
- }
-
- // 3. Guest Book:
- if (datasetVersion.getDataset().getGuestbook() != null && datasetVersion.getDataset().getGuestbook().isEnabled() && datasetVersion.getDataset().getGuestbook().getDataverse() != null ) {
- return true;
- }
- return false;
- }
-
public Boolean canSeeTwoRavensExploreButton(){
return false;
}
diff --git a/src/main/java/edu/harvard/iq/dataverse/FilePage.java b/src/main/java/edu/harvard/iq/dataverse/FilePage.java
index 9225805eba1..2850ec2f603 100644
--- a/src/main/java/edu/harvard/iq/dataverse/FilePage.java
+++ b/src/main/java/edu/harvard/iq/dataverse/FilePage.java
@@ -19,6 +19,7 @@
import edu.harvard.iq.dataverse.export.ExportService;
import edu.harvard.iq.dataverse.export.spi.Exporter;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
+import edu.harvard.iq.dataverse.util.FileUtil;
import edu.harvard.iq.dataverse.util.JsfHelper;
import static edu.harvard.iq.dataverse.util.JsfHelper.JH;
import edu.harvard.iq.dataverse.util.SystemConfig;
@@ -91,6 +92,8 @@ public class FilePage implements java.io.Serializable {
TwoRavensHelper twoRavensHelper;
@Inject WorldMapPermissionHelper worldMapPermissionHelper;
+ private static final Logger logger = Logger.getLogger(FilePage.class.getCanonicalName());
+
public String init() {
@@ -157,7 +160,7 @@ public boolean isDownloadPopupRequired() {
if(fileMetadata.getId() == null || fileMetadata.getDatasetVersion().getId() == null ){
return false;
}
- return fileDownloadService.isDownloadPopupRequired(fileMetadata.getDatasetVersion());
+ return FileUtil.isDownloadPopupRequired(fileMetadata.getDatasetVersion());
}
@@ -448,5 +451,13 @@ public boolean isReplacementFile(){
return this.datafileService.isReplacementFile(this.getFile());
}
-
+
+ public boolean isPubliclyDownloadable() {
+ return FileUtil.isPubliclyDownloadable(fileMetadata);
+ }
+
+ public String getPublicDownloadUrl() {
+ return FileUtil.getPublicDownloadUrl(systemConfig.getDataverseSiteUrl(), fileId);
+ }
+
}
diff --git a/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java b/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java
index 73e7ef8c715..f3a9825f72e 100644
--- a/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java
+++ b/src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java
@@ -20,18 +20,16 @@
package edu.harvard.iq.dataverse.util;
-import edu.emory.mathcs.backport.java.util.Collections;
import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.DataFile.ChecksumType;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.FileMetadata;
+import edu.harvard.iq.dataverse.TermsOfUseAndAccess;
import edu.harvard.iq.dataverse.datasetutility.FileExceedsMaxSizeException;
import edu.harvard.iq.dataverse.ingest.IngestReport;
-import edu.harvard.iq.dataverse.ingest.IngestUtil;
import edu.harvard.iq.dataverse.ingest.IngestServiceShapefileHelper;
import edu.harvard.iq.dataverse.ingest.IngestableDataChecker;
import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -56,11 +54,8 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -1182,4 +1177,128 @@ public static String getCiteDataFileFilename(FileMetadata fileMetadata, FileCita
}
}
+ /**
+ * @todo Consider returning not only the boolean but the human readable
+ * reason why the popup is required, which could be used in the GUI to
+ * elaborate on the text "This file cannot be downloaded publicly."
+ */
+ public static boolean isDownloadPopupRequired(DatasetVersion datasetVersion) {
+ // Each of these conditions is sufficient reason to have to
+ // present the user with the popup:
+ if (datasetVersion == null) {
+ logger.fine("Download popup required because datasetVersion is null.");
+ return false;
+ }
+ //0. if version is draft then Popup "not required"
+ if (!datasetVersion.isReleased()) {
+ logger.fine("Download popup required because datasetVersion has not been released.");
+ return false;
+ }
+ // 1. License and Terms of Use:
+ if (datasetVersion.getTermsOfUseAndAccess() != null) {
+ if (!TermsOfUseAndAccess.License.CC0.equals(datasetVersion.getTermsOfUseAndAccess().getLicense())
+ && !(datasetVersion.getTermsOfUseAndAccess().getTermsOfUse() == null
+ || datasetVersion.getTermsOfUseAndAccess().getTermsOfUse().equals(""))) {
+ logger.fine("Download popup required because of license or terms of use.");
+ return true;
+ }
+
+ // 2. Terms of Access:
+ if (!(datasetVersion.getTermsOfUseAndAccess().getTermsOfAccess() == null) && !datasetVersion.getTermsOfUseAndAccess().getTermsOfAccess().equals("")) {
+ logger.fine("Download popup required because of terms of access.");
+ return true;
+ }
+ }
+
+ // 3. Guest Book:
+ if (datasetVersion.getDataset() != null && datasetVersion.getDataset().getGuestbook() != null && datasetVersion.getDataset().getGuestbook().isEnabled() && datasetVersion.getDataset().getGuestbook().getDataverse() != null) {
+ logger.fine("Download popup required because of guestbook.");
+ return true;
+ }
+
+ logger.fine("Download popup is not required.");
+ return false;
+ }
+
+ /**
+ * Provide download URL if no Terms of Use, no guestbook, and not
+ * restricted.
+ */
+ public static boolean isPubliclyDownloadable(FileMetadata fileMetadata) {
+ if (fileMetadata == null) {
+ return false;
+ }
+ if (fileMetadata.isRestricted()) {
+ String msg = "Not publicly downloadable because the file is restricted.";
+ logger.fine(msg);
+ return false;
+ }
+ boolean popupReasons = isDownloadPopupRequired(fileMetadata.getDatasetVersion());
+ if (popupReasons == true) {
+ /**
+ * @todo The user clicking publish may have a bad "Dude, where did
+ * the file Download URL go" experience in the following scenario:
+ *
+ * - The user creates a dataset and uploads a file.
+ *
+ * - The user sets Terms of Use, which means a Download URL should
+ * not be displayed.
+ *
+ * - While the dataset is in draft, the Download URL is displayed
+ * due to the rule "Download popup required because datasetVersion
+ * has not been released."
+ *
+ * - Once the dataset is published the Download URL disappears due
+ * to the rule "Download popup required because of license or terms
+ * of use."
+ *
+ * In short, the Download URL disappears on publish in the scenario
+ * above, which is weird. We should probably attempt to see into the
+ * future to when the dataset is published to see if the file will
+ * be publicly downloadable or not.
+ */
+ return false;
+ }
+ return true;
+ }
+
+ public static String getFileDownloadUrlPath(String downloadType, Long fileId, boolean gbRecordsWritten) {
+ String fileDownloadUrl = "/api/access/datafile/" + fileId;
+ if (downloadType != null && downloadType.equals("bundle")) {
+ fileDownloadUrl = "/api/access/datafile/bundle/" + fileId;
+ }
+ if (downloadType != null && downloadType.equals("original")) {
+ fileDownloadUrl = "/api/access/datafile/" + fileId + "?format=original";
+ }
+ if (downloadType != null && downloadType.equals("RData")) {
+ fileDownloadUrl = "/api/access/datafile/" + fileId + "?format=RData";
+ }
+ if (downloadType != null && downloadType.equals("var")) {
+ fileDownloadUrl = "/api/meta/datafile/" + fileId;
+ }
+ if (downloadType != null && downloadType.equals("tab")) {
+ fileDownloadUrl = "/api/access/datafile/" + fileId + "?format=tab";
+ }
+ if (gbRecordsWritten) {
+ if (downloadType != null && (downloadType.equals("original") || downloadType.equals("RData") || downloadType.equals("tab"))) {
+ fileDownloadUrl += "&gbrecs=true";
+ } else {
+ fileDownloadUrl += "?gbrecs=true";
+ }
+ }
+ logger.fine("Returning file download url: " + fileDownloadUrl);
+ return fileDownloadUrl;
+ }
+
+ public static String getPublicDownloadUrl(String dataverseSiteUrl, Long fileId) {
+ if (fileId == null) {
+ logger.info("In getPublicDownloadUrl but fileId is null!");
+ return null;
+ }
+ String downloadType = null;
+ boolean gbRecordsWritten = false;
+ String path = getFileDownloadUrlPath(downloadType, fileId, gbRecordsWritten);
+ return dataverseSiteUrl + path;
+ }
+
}
diff --git a/src/main/webapp/file.xhtml b/src/main/webapp/file.xhtml
index a462b10e843..88ac46537e0 100644
--- a/src/main/webapp/file.xhtml
+++ b/src/main/webapp/file.xhtml
@@ -222,11 +222,7 @@