Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
milanmajchrak committed Oct 3, 2023
1 parent f874e92 commit 910d66e
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 187 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ public int getSupportsTypeConstant() {
@Override
public InputStream retrieve(Context context, Bitstream bitstream)
throws IOException, SQLException, AuthorizeException {
// Maybe should return AuthorizeException??
authorizeService.authorizeAction(context, bitstream, Constants.READ);

return bitstreamStorageService.retrieve(context, bitstream);
Expand Down
2 changes: 1 addition & 1 deletion dspace-api/src/main/java/org/dspace/util/FileInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ public FileInfo(String name, String size) {
this.size = size;
isDirectory = false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,3 @@ public static String humanReadableFileSize(long bytes) {
return bytes + " " + units[u];
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@
package org.dspace.app.rest;


import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.MetadataBitstreamWrapper;
import org.dspace.app.rest.repository.MetadataBitstreamRestRepository;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.MissingLicenseAgreementException;
Expand Down Expand Up @@ -51,95 +55,102 @@
@RequestMapping("/bitstream")
public class MetadataBitstreamController {

private static Logger log = org.apache.logging.log4j.LogManager.getLogger(MetadataBitstreamController.class);

@Autowired
BitstreamService bitstreamService;

@Autowired
HandleService handleService;
@Autowired
private AuthorizeService authorizeService;

@GetMapping("/handle/{id}/{subId}/{fileName}")
public ResponseEntity<Resource> downloadSingleFile(
@PathVariable("id") String id,
@PathVariable("subId") String subId,
@PathVariable("fileName") String fileName,
HttpServletRequest request, HttpServletResponse response) throws IOException {
public ResponseEntity<Resource> downloadSingleFile(@PathVariable("id") String id,
@PathVariable("subId") String subId,
@PathVariable("fileName") String fileName,
HttpServletRequest request, HttpServletResponse response)
throws IOException {
String handleID = id + "/" + subId;
if (StringUtils.isBlank(handleID)) {
throw new DSpaceBadRequestException("handle cannot be null!");
if (StringUtils.isBlank(id) || StringUtils.isBlank(subId)) {
log.error("Handle cannot be null! PathVariable `id` or `subId` is null.");
throw new DSpaceBadRequestException("Handle cannot be null!");
}

Context context = ContextUtil.obtainContext(request);
if (Objects.isNull(context)) {
log.error("Cannot obtain the context from the request.");
throw new RuntimeException("Cannot obtain the context from the request.");
}

DSpaceObject dso = null;

try{
dso = handleService.resolveToObject(context, handleID);
} catch (Exception e) {
log.error("Cannot resolve handle: " + handleID);
throw new RuntimeException("Cannot resolve handle: " + handleID);
}

if (dso != null && dso instanceof Item) {
Item item = (Item) dso;
List<Bundle> bundles = item.getBundles();
for (Bundle bundle:
bundles) {
for (Bitstream bitstream:
bundle.getBitstreams()) {
try {
authorizeService.authorizeAction(context, bitstream, Constants.READ);
} catch (MissingLicenseAgreementException e) {
response.sendRedirect("http://localhost:4000/bitstream/" + bitstream.getID() + "/download");
} catch (AuthorizeException e) {
response.sendRedirect("http://localhost:4000" + "/login");
} catch (SQLException e) {
response.sendRedirect("http://localhost:4000" + "/login");
}
String btName = bitstream.getName();
if (btName.equalsIgnoreCase(fileName)) {
try {
BitstreamFormat bitstreamFormat = bitstream.getFormat(context);
if (bitstreamFormat == null || bitstreamFormat.getExtensions() == null || bitstreamFormat.getExtensions().size() == 0) {
// throw new RuntimeException("Cannot find the bitstream format.");
}
InputStream inputStream = bitstreamService.retrieve(context, bitstream);
InputStreamResource resource = new InputStreamResource(inputStream);
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=" + fileName);
// "attachment; filename=" + fileName +".pdf");
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
return ResponseEntity.ok()
.headers(header)
.contentLength(inputStream.available())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

if (Objects.isNull(dso)) {
log.error("DSO is null");
return null;
}

if (!(dso instanceof Item)) {
log.error("DSO is not instance of Item");
return null;
}

Item item = (Item) dso;
List<Bundle> bundles = item.getBundles();
for (Bundle bundle: bundles) {
for (Bitstream bitstream: bundle.getBitstreams()) {
// Authorize the action - it will send response redirect if something gets wrong.
authorizeBitstreamAction(context, bitstream, response);

String btName = bitstream.getName();
if (!(btName.equalsIgnoreCase(fileName))) {
continue;
}
try {
BitstreamFormat bitstreamFormat = bitstream.getFormat(context);
// Check if the bitstream has some extensions e.g., `.txt, .jpg,..`
checkBitstreamExtensions(bitstreamFormat);

InputStream inputStream = bitstreamService.retrieve(context, bitstream);
InputStreamResource resource = new InputStreamResource(inputStream);
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=" + fileName);
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
return ResponseEntity.ok()
.headers(header)
.contentLength(inputStream.available())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

return null;
}


@GetMapping("/allzip")
public void downloadFileZip(@RequestParam("handleId") String handleId,
HttpServletResponse response,
HttpServletRequest request) throws IOException, SQLException, AuthorizeException {
//TODO handle authorization
if (StringUtils.isBlank(handleId)) {
throw new DSpaceBadRequestException("handle cannot be null!");
log.error("Handle cannot be null!");
throw new DSpaceBadRequestException("Handle cannot be null!");
}
Context context = ContextUtil.obtainContext(request);
if (Objects.isNull(context)) {
log.error("Cannot obtain the context from the request.");
throw new RuntimeException("Cannot obtain the context from the request.");
}

Expand All @@ -148,41 +159,60 @@ public void downloadFileZip(@RequestParam("handleId") String handleId,
try{
dso = handleService.resolveToObject(context, handleId);
} catch (Exception e) {
log.error("Cannot resolve handle: " + handleId);
throw new RuntimeException("Cannot resolve handle: " + handleId);
}

if (dso != null && dso instanceof Item) {
Item item = (Item) dso;
name = item.getName() + ".zip";
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment;filename=\"%s\"", name));
response.setContentType("application/zip");
List<Bundle> bundles = item.getBundles("ORIGINAL");


ZipArchiveOutputStream zip = new ZipArchiveOutputStream(response.getOutputStream());
zip.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS);
zip.setLevel(Deflater.NO_COMPRESSION);
for (Bundle original : bundles) {
List<Bitstream> bss = original.getBitstreams();
for (Bitstream bitstream : bss) {
try {
authorizeService.authorizeAction(context, bitstream, Constants.READ);
} catch (AuthorizeException e) {
response.sendRedirect("http://localhost:4000" + "/login");
} catch (SQLException e) {
response.sendRedirect("http://localhost:4000" + "/login");
}
String filename = bitstream.getName();
ZipArchiveEntry ze = new ZipArchiveEntry(filename);
zip.putArchiveEntry(ze);
InputStream is = bitstreamService.retrieve(context, bitstream);
IOUtils.copy(is, zip);
zip.closeArchiveEntry();
is.close();
}
if (Objects.isNull(dso)) {
log.error("DSO is null");
throw new UnprocessableEntityException("Retrieved DSO is null, handle: " + handleId);
}

if (!(dso instanceof Item)) {
log.info("DSO is not instance of Item");
}

Item item = (Item) dso;
name = item.getName() + ".zip";
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment;filename=\"%s\"", name));
response.setContentType("application/zip");
List<Bundle> bundles = item.getBundles("ORIGINAL");

ZipArchiveOutputStream zip = new ZipArchiveOutputStream(response.getOutputStream());
zip.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS);
zip.setLevel(Deflater.NO_COMPRESSION);
for (Bundle original : bundles) {
List<Bitstream> bss = original.getBitstreams();
for (Bitstream bitstream : bss) {
authorizeBitstreamAction(context, bitstream, response);

String filename = bitstream.getName();
ZipArchiveEntry ze = new ZipArchiveEntry(filename);
zip.putArchiveEntry(ze);
InputStream is = bitstreamService.retrieve(context, bitstream);
IOUtils.copy(is, zip);
zip.closeArchiveEntry();
is.close();
}
zip.close();
response.getOutputStream().flush();
}
zip.close();
response.getOutputStream().flush();
}

private void authorizeBitstreamAction(Context context, Bitstream bitstream, HttpServletResponse response)
throws IOException {
try {
authorizeService.authorizeAction(context, bitstream, Constants.READ);
} catch (MissingLicenseAgreementException e) {
response.sendRedirect("http://localhost:4000/bitstream/" + bitstream.getID() + "/download");
} catch (AuthorizeException | SQLException e) {
response.sendRedirect("http://localhost:4000" + "/login");
}
}

private void checkBitstreamExtensions(BitstreamFormat bitstreamFormat) {
if ( Objects.isNull(bitstreamFormat) || CollectionUtils.isEmpty(bitstreamFormat.getExtensions())) {
throw new RuntimeException("Bitstream Extensions cannot be empty for downloading/previewing bitstreams.");
}
}
}
Loading

0 comments on commit 910d66e

Please sign in to comment.