Skip to content

Commit cbb925b

Browse files
committed
A quick implementation of a better/prettier file name for the multi-file zipped bundle. #9620
1 parent e3b82e4 commit cbb925b

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

src/main/java/edu/harvard/iq/dataverse/api/Access.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ public class Access extends AbstractApiBean {
169169
@Inject
170170
DataverseFeaturedItemServiceBean dataverseFeaturedItemServiceBean;
171171

172+
private static final String DEFAULT_BUNDLE_NAME = "dataverse_files.zip";
172173
//@EJB
173174

174175
// TODO:
@@ -749,6 +750,20 @@ private static String getFileIdsAsCommaSeparated(List<FileMetadata> fileMetadata
749750
}
750751
return String.join(",", ids);
751752
}
753+
754+
private String generateMultiFileBundleName(Dataset dataset) {
755+
String bundleName = DEFAULT_BUNDLE_NAME;
756+
757+
if (dataset != null) {
758+
String protocol = dataset.getProtocol();
759+
String authority = dataset.getAuthority().toLowerCase();
760+
String identifier = dataset.getIdentifier().replace('/', '-').toLowerCase();
761+
762+
bundleName = protocol + "-" + authority + "-" + identifier + ".zip";
763+
}
764+
765+
return bundleName;
766+
}
752767

753768
/*
754769
* API method for downloading zipped bundles of multiple files:
@@ -852,8 +867,9 @@ public void write(OutputStream os) throws IOException,
852867
// to produce some output.
853868
zipper = new DataFileZipper(os);
854869
zipper.setFileManifest(fileManifest);
855-
response.setHeader("Content-disposition", "attachment; filename=\"dataverse_files.zip\"");
856-
response.setHeader("Content-Type", "application/zip; name=\"dataverse_files.zip\"");
870+
String bundleName = generateMultiFileBundleName(file.getOwner());
871+
response.setHeader("Content-disposition", "attachment; filename=\"" + bundleName + "\"");
872+
response.setHeader("Content-Type", "application/zip; name=\"" + bundleName + "\"");
857873
}
858874

859875
long size = 0L;
@@ -960,8 +976,8 @@ public InputStream tempPreview(@PathParam("fileSystemId") String fileSystemId, @
960976
961977
}*/
962978

963-
964-
979+
980+
965981
// TODO: Rather than only supporting looking up files by their database IDs, consider supporting persistent identifiers.
966982
@Path("fileCardImage/{fileId}")
967983
@GET

src/test/java/edu/harvard/iq/dataverse/api/AccessIT.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.io.ByteArrayOutputStream;
2222
import java.io.InputStream;
2323
import java.util.HashMap;
24+
import java.util.regex.Matcher;
25+
import java.util.regex.Pattern;
2426

2527
import org.hamcrest.collection.IsMapContaining;
2628

@@ -43,7 +45,8 @@ public class AccessIT {
4345
public static String apiToken;
4446
public static String dataverseAlias;
4547
public static Integer datasetId;
46-
48+
public static String persistentId;
49+
4750
public static Integer basicFileId;
4851
public static Integer tabFile1Id;
4952
public static Integer tabFile2Id;
@@ -78,7 +81,6 @@ public class AccessIT {
7881
private static String testFileFromZipUploadWithFoldersChecksum1 = "8f326944be21361ad8219bc3269bc9eb";
7982
private static String testFileFromZipUploadWithFoldersChecksum2 = "0fe4efd85229bad6e587fd3f1a6c8e05";
8083
private static String testFileFromZipUploadWithFoldersChecksum3 = "00433ccb20111f9d40f0e5ab6fa8396f";
81-
8284

8385
@BeforeAll
8486
public static void setUp() throws InterruptedException {
@@ -101,6 +103,7 @@ public static void setUp() throws InterruptedException {
101103
Response createDatasetResponse = UtilIT.createDatasetViaNativeApi(dataverseAlias, pathToJsonFile, apiToken);
102104
createDatasetResponse.prettyPrint();
103105
datasetId = JsonPath.from(createDatasetResponse.body().asString()).getInt("data.id");
106+
persistentId = JsonPath.from(createDatasetResponse.body().asString()).getString("data.persistentId");
104107

105108
Response allowAccessRequests = UtilIT.allowAccessRequests(datasetId.toString(), true, apiToken);
106109
allowAccessRequests.prettyPrint();
@@ -285,7 +288,27 @@ public void testDownloadMultipleFiles_NonLoggedInOpen() throws IOException {
285288
assertThat(files2, IsMapContaining.hasKey(tabFile2NameConvert));
286289

287290
System.out.println("origSize: " + origSizeAnon + " | convertSize: " + convertSizeAnon);
288-
assertThat(origSizeAnon, is(not(convertSizeAnon)));
291+
assertThat(origSizeAnon, is(not(convertSizeAnon)));
292+
293+
// Finally, verify that the multi-file bundle produced by the API
294+
// is properly named (as of v6.7 this should be a pretty name based on
295+
// the persistent Id of the dataset).
296+
297+
String contentDispositionHeader = anonDownloadConverted.getHeader("Content-disposition");
298+
System.out.println("Response header: "+contentDispositionHeader);
299+
300+
Pattern regexPattern = Pattern.compile("attachment; filename=\"([a-z0-9\\.-]*\\.zip)\"");
301+
Matcher regexMatcher = regexPattern.matcher(contentDispositionHeader);
302+
boolean regexMatch = regexMatcher.find();
303+
assertTrue(regexMatch);
304+
305+
String expectedPrettyName = persistentId.replaceAll("[:/]", "-").toLowerCase() + ".zip";
306+
System.out.println("expected \"pretty\" file name of the zipped multi-file bundle: " + expectedPrettyName);
307+
308+
String fileBundleName = regexMatcher.group(1);
309+
System.out.println("file name found in the header: "+fileBundleName);
310+
311+
assertEquals(fileBundleName, expectedPrettyName);
289312
}
290313

291314
@Test

0 commit comments

Comments
 (0)