Skip to content
159 changes: 154 additions & 5 deletions src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,14 @@ public enum DisplayMode {
private Boolean hasRsyncScript = false;

private Boolean hasTabular = false;

/**
* If the dataset version has at least one tabular file. The "hasTabular"
* boolean is for the dataset level ("has ever had a tabular file") but
* sometimes you want to know about the current version ("no tabular files
* currently"). Like all files, tabular files can be deleted.
*/
private boolean versionHasTabular = false;

private boolean showIngestSuccess;

Expand Down Expand Up @@ -2037,7 +2045,18 @@ private String init(boolean initFull) {

displayLockInfo(dataset);

for (FileMetadata fmd : workingVersion.getFileMetadatas()) {
if (fmd.getDataFile().isTabularData()) {
versionHasTabular = true;
break;
}
}
for(DataFile f : dataset.getFiles()) {
// TODO: Consider uncommenting this optimization.
// if (versionHasTabular) {
// hasTabular = true;
// break;
// }
if(f.isTabularData()) {
hasTabular = true;
break;
Expand Down Expand Up @@ -2257,8 +2276,11 @@ private DefaultTreeNode createFileTreeNode(FileMetadata fileMetadata, TreeNode p
public boolean isHasTabular() {
return hasTabular;
}



public boolean isVersionHasTabular() {
return versionHasTabular;
}

public boolean isReadOnly() {
return readOnly;
}
Expand Down Expand Up @@ -2886,8 +2908,43 @@ public List<FileMetadata> getSelectedNonDownloadableFiles() {
public void setSelectedNonDownloadableFiles(List<FileMetadata> selectedNonDownloadableFiles) {
this.selectedNonDownloadableFiles = selectedNonDownloadableFiles;
}



private List<FileMetadata> selectedNonDownloadallableFiles;

public List<FileMetadata> getSelectedNonDownloadallableFiles() {
return selectedNonDownloadallableFiles;
}

public void setSelectedNonDownloadallableFiles(List<FileMetadata> selectedNonDownloadallableFiles) {
this.selectedNonDownloadallableFiles = selectedNonDownloadallableFiles;
}

public String getSizeOfDataset() {
boolean original = false;
return DatasetUtil.getDownloadSize(workingVersion, original);
}

public String getSizeOfDatasetOrig() {
boolean original = true;
return DatasetUtil.getDownloadSize(workingVersion, original);
}

public void validateAllFilesForDownloadArchival() {
boolean guestbookRequired = isDownloadPopupRequired();
boolean downloadOriginal = false;
validateFilesForDownloadAll(guestbookRequired, downloadOriginal);
}

/**
* Can result in "requested optional service" error. For non-tabular files
* it's safer to use validateAllFilesForDownloadArchival.
*/
public void validateAllFilesForDownloadOriginal() {
boolean guestbookRequired = isDownloadPopupRequired();
boolean downloadOriginal = true;
validateFilesForDownloadAll(guestbookRequired, downloadOriginal);
}

public void validateFilesForDownload(boolean guestbookRequired, boolean downloadOriginal){
setSelectedDownloadableFiles(new ArrayList<>());
setSelectedNonDownloadableFiles(new ArrayList<>());
Expand Down Expand Up @@ -2951,7 +3008,77 @@ public void validateFilesForDownload(boolean guestbookRequired, boolean download
}

}


/**
* This method borrows heavily from validateFilesForDownload but does not
* use the selectedFiles field.
*/
public void validateFilesForDownloadAll(boolean guestbookRequired, boolean downloadOriginal) {
setSelectedNonDownloadallableFiles(new ArrayList<>());
List<FileMetadata> downloadableFiles = new ArrayList<>();
for (FileMetadata fmd : workingVersion.getFileMetadatas()) {
if (this.fileDownloadHelper.canDownloadFile(fmd)) {
downloadableFiles.add(fmd);
} else {
getSelectedNonDownloadallableFiles().add(fmd);
}
}

// If some of the files were restricted and we had to drop them off the
// list, and NONE of the files are left on the downloadable list
// - we show them a "you're out of luck" popup:
if (downloadableFiles.isEmpty() && !getSelectedNonDownloadallableFiles().isEmpty()) {
//RequestContext requestContext = RequestContext.getCurrentInstance();
PrimeFaces.current().executeScript("PF('downloadInvalid').show()");
return;
}

// Note that the GuestbookResponse object may still have information from
// the last download action performed by the user. For example, it may
// still have the non-null Datafile in it, if the user has just downloaded
// a single file; or it may still have the format set to "original" -
// even if that's not what they are trying to do now.
// So make sure to reset these values:
guestbookResponse.setDataFile(null);
// Inline getSelectedDownloadableFilesIdsString() that doesn't use selectedDownloadableFiles
String downloadIdString = "";
for (FileMetadata fmd : downloadableFiles) {
if (!StringUtil.isEmpty(downloadIdString)) {
downloadIdString += ",";
}
downloadIdString += fmd.getDataFile().getId();
}
guestbookResponse.setSelectedFileIds(downloadIdString);
if (downloadOriginal) {
guestbookResponse.setFileFormat("original");
} else {
guestbookResponse.setFileFormat("");
}
guestbookResponse.setDownloadtype("Download");

// If we have a bunch of files that we can download, AND there were no files
// that we had to take off the list, because of permissions - we can
// either send the user directly to the download API (if no guestbook/terms
// popup is required), or send them to the download popup:
if (!downloadableFiles.isEmpty() && getSelectedNonDownloadallableFiles().isEmpty()) {
if (guestbookRequired) {
openDownloadPopupForDownloadAll();
} else {
startMultipleFileDownload();
}
return;
}

// ... and if some files were restricted, but some are downloadable,
// we are showing them this "you are somewhat in luck" popup; that will
// then direct them to the download, or popup, as needed:
if (!downloadableFiles.isEmpty() && !getSelectedNonDownloadallableFiles().isEmpty()) {
//RequestContext requestContext = RequestContext.getCurrentInstance();
PrimeFaces.current().executeScript("PF('downloadAllMixed').show()");
}

}

private boolean selectAllFiles;

public boolean isSelectAllFiles() {
Expand Down Expand Up @@ -4073,6 +4200,28 @@ public void openDownloadPopupForMultipleFileDownload() {
//RequestContext requestContext = RequestContext.getCurrentInstance();
PrimeFaces.current().executeScript("PF('downloadPopup').show();handleResizeDialog('downloadPopup');");
}

/**
* This method borrows heavily from
* openDownloadPopupForMultipleFileDownload. It does not use the
* selectedFiles field.
*/
public void openDownloadPopupForDownloadAll() {
// This is commented out because "download all" doesn't use selectedFiles.
// if (this.selectedFiles.isEmpty()) {
// //RequestContext requestContext = RequestContext.getCurrentInstance();
// PrimeFaces.current().executeScript("PF('selectFilesForDownload').show()");
// return;
// }

// There's a chance that this is not really a batch download - i.e.,
// there may only be one file on the downloadable list. But the fileDownloadService
// method below will check for that, and will redirect to the single download, if
// that's the case. -- L.A.
this.guestbookResponse.setDownloadtype("Download");
//RequestContext requestContext = RequestContext.getCurrentInstance();
PrimeFaces.current().executeScript("PF('downloadPopup').show();handleResizeDialog('downloadPopup');");
}

public void initGuestbookMultipleResponse(String selectedFileIds){
initGuestbookResponse(null, "download", selectedFileIds);
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/dataset/DatasetUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import static edu.harvard.iq.dataverse.dataaccess.DataAccess.getStorageIO;
import static edu.harvard.iq.dataverse.dataaccess.DataAccess.getStorageIO;
import static edu.harvard.iq.dataverse.dataaccess.DataAccess.getStorageIO;
import edu.harvard.iq.dataverse.datasetutility.FileSizeChecker;

public class DatasetUtil {

Expand Down Expand Up @@ -440,4 +441,24 @@ public static List<DatasetField> getDatasetSummaryFields(DatasetVersion datasetV
return datasetFields;
}

/**
* Given a dataset version, return it's size in human readable units such as
* 42.9 MB.There is a GetDatasetStorageSizeCommand but it's overly complex
* for the use case.
*
* @param original Use the original file size rather than the archival file
* size for tabular files.
*/
public static String getDownloadSize(DatasetVersion dsv, boolean original) {
long bytes = 0l;
for (FileMetadata fileMetadata : dsv.getFileMetadatas()) {
DataFile dataFile = fileMetadata.getDataFile();
if (original && dataFile.isTabularData()) {
bytes += dataFile.getOriginalFileSize();
} else {
bytes += dataFile.getFilesize();
}
}
return FileSizeChecker.bytesToHumanReadable(bytes);
}
}
1 change: 1 addition & 0 deletions src/main/java/propertyFiles/Bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,7 @@ dataset.accessBtn=Access Dataset
dataset.accessBtn.header.download=Download Options
dataset.accessBtn.header.explore=Explore Options
dataset.accessBtn.header.compute=Compute Options
dataset.accessBtn.download.size=ZIP ({0})
dataset.linkBtn=Link Dataset
dataset.contactBtn=Contact Owner
dataset.shareBtn=Share
Expand Down
59 changes: 49 additions & 10 deletions src/main/webapp/dataset.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@
and !permissionsWrapper.canIssuePublishDatasetCommand(DatasetPage.dataset)}"/>
<ui:param name="showReturnToAuthorLink" value="#{DatasetPage.dataset.latestVersion.versionState=='DRAFT' and DatasetPage.dataset.latestVersion.inReview
and permissionsWrapper.canIssuePublishDatasetCommand(DatasetPage.dataset)}"/>
<!-- TO-DO #3513 DOWNLOAD ALL LINK -->
<!-- ADDED TOOLS SPECIFIC LOGIC TO DatasetPage.canDownloadFiles() RENDER LOGIC, CAN BE REMOVED WHEN DOWNLOAD ALL FILES IS WIRED UP -->
<ui:param name="showAccessDatasetButtonGroup" value="#{(DatasetPage.canDownloadFiles()
and (DatasetPage.datasetExploreTools.size() >= 1
or (DatasetPage.sessionUserAuthenticated and DatasetPage.showComputeButton())))
<ui:param name="showAccessDatasetButtonGroup" value="#{DatasetPage.canDownloadFiles()
and (!DatasetPage.workingVersion.deaccessioned
or (DatasetPage.workingVersion.deaccessioned and DatasetPage.canUpdateDataset()))}"/>
<ui:param name="publishDataset" value="#{DatasetPage.publishDatasetPopup()}"/>
Expand Down Expand Up @@ -143,17 +139,38 @@
</button>
<ul class="dropdown-menu pull-right text-left">

<ui:remove>
<!-- DOWNLOAD -->
<!-- TO-DO #3513 DOWNLOAD ALL LINK -->
<ui:fragment rendered="#{DatasetPage.canDownloadFiles()}">
<li class="dropdown-header">#{bundle['dataset.accessBtn.header.download']} <span class="glyphicon glyphicon-download-alt"/></li>
<li class="disabled">
<span class="ui-commandlink ui-widget ui-state-disabled btn-download">Download (Placeholder)</span>
<!-- NORMAL DOWNLOAD BUTTON (NO TABULAR FILES) -->
<li jsf:rendered="#{!DatasetPage.versionHasTabular}">
<p:commandLink update="@form" actionListener="#{DatasetPage.validateAllFilesForDownloadArchival()}" styleClass="btn-download">
#{bundle.download}
<h:outputFormat value="#{bundle['dataset.accessBtn.download.size']}">
<f:param value="#{DatasetPage.sizeOfDataset}" />
</h:outputFormat>
</p:commandLink>
</li>
<!-- DOWNLOAD ORIGINAL BUTTON (TABULAR FILES PRESENT) -->
<li jsf:rendered="#{DatasetPage.versionHasTabular}">
<p:commandLink update="@form" actionListener="#{DatasetPage.validateAllFilesForDownloadOriginal()}" styleClass="btn-download">
#{bundle.downloadOriginal}
<h:outputFormat value="#{bundle['dataset.accessBtn.download.size']}">
<f:param value="#{DatasetPage.sizeOfDatasetOrig}" />
</h:outputFormat>
</p:commandLink>
</li>
<!-- DOWNLOAD ARCHIVAL FILES (TABULAR FILES PRESENT) -->
<li jsf:rendered="#{DatasetPage.versionHasTabular}">
<p:commandLink update="@form" actionListener="#{DatasetPage.validateAllFilesForDownloadArchival()}" styleClass="btn-download">
#{bundle.downloadArchival}
<h:outputFormat value="#{bundle['dataset.accessBtn.download.size']}">
<f:param value="#{DatasetPage.sizeOfDataset}" />
</h:outputFormat>
</p:commandLink>
</li>
</ui:fragment>
<!-- END: DOWNLOAD -->
</ui:remove>

<!-- EXPLORE -->
<ui:fragment rendered="#{DatasetPage.datasetExploreTools.size() >= 1}">
Expand Down Expand Up @@ -872,6 +889,28 @@
</button>
</div>
</p:dialog>
<p:dialog id="downloadAllMixed" styleClass="smallPopUp" header="#{bundle['dataset.inValidSelectedFilesForDownload']}" widgetVar="downloadAllMixed" modal="true">
<p class="text-danger"><span class="glyphicon glyphicon-exclamation-sign"/> #{bundle['dataset.mixedSelectedFilesForDownload']}</p>
<table>
<ui:repeat var="resFile" value="#{DatasetPage.selectedNonDownloadallableFiles}" >
<tr>
<td>#{resFile.label}</td>
</tr>
</ui:repeat>
</table>
<div class="button-block">
<p class="help-block">#{bundle['dataset.downloadUnrestricted']}</p>
<p:commandButton styleClass="btn btn-default" value="#{bundle.continue}" onclick="PF('downloadAllMixed').hide()"
rendered="#{!DatasetPage.downloadPopupRequired}"
action="#{DatasetPage.startMultipleFileDownload()}"/>
<p:commandButton styleClass="btn btn-default" value="#{bundle.continue}" onclick="PF('downloadAllMixed').hide()"
rendered="#{DatasetPage.downloadPopupRequired and !settingsWrapper.rsyncDownload}"
action="#{DatasetPage.openDownloadPopupForDownloadAll()}" update="@form"/>
<button class="btn btn-link" onclick="PF('downloadAllMixed').hide();" type="button">
#{bundle.cancel}
</button>
</div>
</p:dialog>
<p:dialog id="deleteConfirmation" styleClass="smallPopUp" header="#{bundle['file.deleteDialog.header']}" widgetVar="deleteConfirmation" modal="true">
<p class="text-warning"><span class="glyphicon glyphicon-warning-sign"/> #{bundle['file.deleteDialog.tip']}</p>
<div class="button-block">
Expand Down