mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-14 10:34:06 +02:00
Migrate stream to resource for stability (#6160)
This commit is contained in:
@@ -10,6 +10,7 @@ import java.nio.file.Path;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||||
@@ -157,13 +158,48 @@ public class FileStorage {
|
|||||||
success = true;
|
success = true;
|
||||||
} finally {
|
} finally {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
try {
|
||||||
Files.deleteIfExists(filePath);
|
Files.deleteIfExists(filePath);
|
||||||
|
} catch (IOException cleanupEx) {
|
||||||
|
log.warn(
|
||||||
|
"Failed to clean up partial file {} after store failure",
|
||||||
|
filePath,
|
||||||
|
cleanupEx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.debug("Stored StreamingResponseBody with ID: {}", fileId);
|
log.debug("Stored StreamingResponseBody with ID: {}", fileId);
|
||||||
return fileId;
|
return fileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persist a {@link Resource} body to disk, returning the generated file ID. Used by the async
|
||||||
|
* job pipeline to capture {@code ResponseEntity<Resource>} results produced by controllers.
|
||||||
|
*/
|
||||||
|
public String storeFromResource(Resource resource, String originalName) throws IOException {
|
||||||
|
String fileId = generateFileId();
|
||||||
|
Path filePath = getFilePath(fileId);
|
||||||
|
Files.createDirectories(filePath.getParent());
|
||||||
|
boolean success = false;
|
||||||
|
try (InputStream in = resource.getInputStream()) {
|
||||||
|
Files.copy(in, filePath);
|
||||||
|
success = true;
|
||||||
|
} finally {
|
||||||
|
if (!success) {
|
||||||
|
try {
|
||||||
|
Files.deleteIfExists(filePath);
|
||||||
|
} catch (IOException cleanupEx) {
|
||||||
|
log.warn(
|
||||||
|
"Failed to clean up partial file {} after store failure",
|
||||||
|
filePath,
|
||||||
|
cleanupEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.debug("Stored Resource with ID: {}", fileId);
|
||||||
|
return fileId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a file by its ID
|
* Delete a file by its ID
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -321,6 +322,13 @@ public class JobExecutorService {
|
|||||||
log.debug(
|
log.debug(
|
||||||
"Stored ResponseEntity<StreamingResponseBody> result with fileId: {}",
|
"Stored ResponseEntity<StreamingResponseBody> result with fileId: {}",
|
||||||
fileId);
|
fileId);
|
||||||
|
} else if (body instanceof Resource resource) {
|
||||||
|
String filename = extractResponseFilename(response);
|
||||||
|
String contentType = extractResponseContentType(response);
|
||||||
|
|
||||||
|
String fileId = fileStorage.storeFromResource(resource, filename);
|
||||||
|
taskManager.setFileResult(jobId, fileId, filename, contentType);
|
||||||
|
log.debug("Stored ResponseEntity<Resource> result with fileId: {}", fileId);
|
||||||
} else {
|
} else {
|
||||||
// Check if the response body contains a fileId
|
// Check if the response body contains a fileId
|
||||||
if (body != null && body.toString().contains("fileId")) {
|
if (body != null && body.toString().contains("fileId")) {
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ import java.util.zip.ZipOutputStream;
|
|||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
|
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
|
||||||
import com.vladsch.flexmark.util.data.MutableDataSet;
|
import com.vladsch.flexmark.util.data.MutableDataSet;
|
||||||
@@ -49,7 +49,7 @@ public class PDFToFile {
|
|||||||
this.runtimePathConfig = runtimePathConfig;
|
this.runtimePathConfig = runtimePathConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToMarkdown(MultipartFile inputFile)
|
public ResponseEntity<Resource> processPdfToMarkdown(MultipartFile inputFile)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
if (!MediaType.APPLICATION_PDF_VALUE.equals(inputFile.getContentType())) {
|
if (!MediaType.APPLICATION_PDF_VALUE.equals(inputFile.getContentType())) {
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
@@ -169,7 +169,7 @@ public class PDFToFile {
|
|||||||
return PATTERN.matcher(markdown).replaceAll("$1(images/$2)");
|
return PATTERN.matcher(markdown).replaceAll("$1(images/$2)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToHtml(MultipartFile inputFile)
|
public ResponseEntity<Resource> processPdfToHtml(MultipartFile inputFile)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
if (!MediaType.APPLICATION_PDF_VALUE.equals(inputFile.getContentType())) {
|
if (!MediaType.APPLICATION_PDF_VALUE.equals(inputFile.getContentType())) {
|
||||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||||
@@ -232,7 +232,7 @@ public class PDFToFile {
|
|||||||
finalOut, fileName, MediaType.APPLICATION_OCTET_STREAM);
|
finalOut, fileName, MediaType.APPLICATION_OCTET_STREAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToOfficeFormat(
|
public ResponseEntity<Resource> processPdfToOfficeFormat(
|
||||||
MultipartFile inputFile, String outputFormat, String libreOfficeFilter)
|
MultipartFile inputFile, String outputFormat, String libreOfficeFilter)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
package stirling.software.common.util;
|
package stirling.software.common.util;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FilterInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
|
|
||||||
@@ -49,12 +52,7 @@ public class WebResponseUtils {
|
|||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentType(mediaType);
|
headers.setContentType(mediaType);
|
||||||
headers.setContentLength(bytes.length);
|
headers.setContentLength(bytes.length);
|
||||||
String encodedDocName =
|
headers.setContentDispositionFormData("attachment", encodeAttachmentName(docName));
|
||||||
RegexPatternUtils.getInstance()
|
|
||||||
.getPlusSignPattern()
|
|
||||||
.matcher(URLEncoder.encode(docName, StandardCharsets.UTF_8))
|
|
||||||
.replaceAll("%20");
|
|
||||||
headers.setContentDispositionFormData("attachment", encodedDocName);
|
|
||||||
return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
|
return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +71,17 @@ public class WebResponseUtils {
|
|||||||
return baosToWebResponse(baos, docName);
|
return baosToWebResponse(baos, docName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResponseEntity<StreamingResponseBody> pdfDocToWebResponse(
|
/**
|
||||||
|
* Save a {@link PDDocument} to a managed temp file and return it as a file-backed {@code
|
||||||
|
* ResponseEntity<Resource>}.
|
||||||
|
*
|
||||||
|
* <p>The returned {@link Resource} owns the supplied {@link TempFile} — the file is deleted
|
||||||
|
* when Spring closes the response {@link InputStream} after writing the body. This is a
|
||||||
|
* synchronous equivalent of the previous {@code StreamingResponseBody} pattern and avoids the
|
||||||
|
* async-dispatch hazards (response-committed races, filter incompatibility, silent write
|
||||||
|
* failures) that {@code StreamingResponseBody} introduced.
|
||||||
|
*/
|
||||||
|
public static ResponseEntity<Resource> pdfDocToWebResponse(
|
||||||
PDDocument document, String docName, TempFileManager tempFileManager)
|
PDDocument document, String docName, TempFileManager tempFileManager)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
TempFile tempFile = tempFileManager.createManagedTempFile(".pdf");
|
TempFile tempFile = tempFileManager.createManagedTempFile(".pdf");
|
||||||
@@ -87,38 +95,49 @@ public class WebResponseUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a File to a web response (PDF default).
|
* Convert a {@link TempFile} holding a PDF into a web response.
|
||||||
|
*
|
||||||
|
* <p>The temp file is deleted when Spring closes the response body stream.
|
||||||
*
|
*
|
||||||
* @param outputTempFile The temporary file to be sent as a response.
|
* @param outputTempFile The temporary file to be sent as a response.
|
||||||
* @param docName The name of the document.
|
* @param docName The name of the document.
|
||||||
* @return A ResponseEntity containing the file as a resource.
|
* @return A ResponseEntity whose body streams the file, deleting it on close.
|
||||||
*/
|
*/
|
||||||
public static ResponseEntity<StreamingResponseBody> pdfFileToWebResponse(
|
public static ResponseEntity<Resource> pdfFileToWebResponse(
|
||||||
TempFile outputTempFile, String docName) throws IOException {
|
TempFile outputTempFile, String docName) throws IOException {
|
||||||
return fileToWebResponse(outputTempFile, docName, MediaType.APPLICATION_PDF);
|
return fileToWebResponse(outputTempFile, docName, MediaType.APPLICATION_PDF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a File to a web response (ZIP default).
|
* Convert a {@link TempFile} holding a ZIP archive into a web response.
|
||||||
|
*
|
||||||
|
* <p>The temp file is deleted when Spring closes the response body stream.
|
||||||
*
|
*
|
||||||
* @param outputTempFile The temporary file to be sent as a response.
|
* @param outputTempFile The temporary file to be sent as a response.
|
||||||
* @param docName The name of the document.
|
* @param docName The name of the document.
|
||||||
* @return A ResponseEntity containing the file as a resource.
|
* @return A ResponseEntity whose body streams the file, deleting it on close.
|
||||||
*/
|
*/
|
||||||
public static ResponseEntity<StreamingResponseBody> zipFileToWebResponse(
|
public static ResponseEntity<Resource> zipFileToWebResponse(
|
||||||
TempFile outputTempFile, String docName) throws IOException {
|
TempFile outputTempFile, String docName) throws IOException {
|
||||||
return fileToWebResponse(outputTempFile, docName, MediaType.APPLICATION_OCTET_STREAM);
|
return fileToWebResponse(outputTempFile, docName, MediaType.APPLICATION_OCTET_STREAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a File to a web response with explicit media type (e.g., ZIP).
|
* Convert a {@link TempFile} into a web response with an explicit media type.
|
||||||
|
*
|
||||||
|
* <p>The returned {@link ResponseEntity} carries a {@link ManagedTempFileResource} as its body.
|
||||||
|
* Spring's {@code ResourceHttpMessageConverter} calls {@link Resource#getInputStream()} once
|
||||||
|
* and closes the returned stream after writing — at which point the underlying {@link TempFile}
|
||||||
|
* is deleted. Everything runs synchronously on the request thread, so write failures propagate
|
||||||
|
* through normal Spring error handling and are logged, rather than silently truncating the
|
||||||
|
* response.
|
||||||
*
|
*
|
||||||
* @param outputTempFile The temporary file to be sent as a response.
|
* @param outputTempFile The temporary file to be sent as a response.
|
||||||
* @param docName The name of the document.
|
* @param docName The name of the document.
|
||||||
* @param mediaType The content type to set on the response.
|
* @param mediaType The content type to set on the response.
|
||||||
* @return A ResponseEntity containing the file as a resource.
|
* @return A ResponseEntity whose body streams the file, deleting it on close.
|
||||||
*/
|
*/
|
||||||
public static ResponseEntity<StreamingResponseBody> fileToWebResponse(
|
public static ResponseEntity<Resource> fileToWebResponse(
|
||||||
TempFile outputTempFile, String docName, MediaType mediaType) throws IOException {
|
TempFile outputTempFile, String docName, MediaType mediaType) throws IOException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -127,23 +146,9 @@ public class WebResponseUtils {
|
|||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentType(mediaType);
|
headers.setContentType(mediaType);
|
||||||
headers.setContentLength(len);
|
headers.setContentLength(len);
|
||||||
String encodedDocName =
|
headers.setContentDispositionFormData("attachment", encodeAttachmentName(docName));
|
||||||
RegexPatternUtils.getInstance()
|
|
||||||
.getPlusSignPattern()
|
|
||||||
.matcher(URLEncoder.encode(docName, StandardCharsets.UTF_8))
|
|
||||||
.replaceAll("%20");
|
|
||||||
headers.setContentDispositionFormData("attachment", encodedDocName);
|
|
||||||
|
|
||||||
StreamingResponseBody body =
|
|
||||||
os -> {
|
|
||||||
try (os) {
|
|
||||||
Files.copy(path, os);
|
|
||||||
os.flush();
|
|
||||||
} finally {
|
|
||||||
outputTempFile.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
Resource body = new ManagedTempFileResource(outputTempFile);
|
||||||
return new ResponseEntity<>(body, headers, HttpStatus.OK);
|
return new ResponseEntity<>(body, headers, HttpStatus.OK);
|
||||||
} catch (IOException | RuntimeException e) {
|
} catch (IOException | RuntimeException e) {
|
||||||
try {
|
try {
|
||||||
@@ -154,4 +159,115 @@ public class WebResponseUtils {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String encodeAttachmentName(String docName) {
|
||||||
|
return RegexPatternUtils.getInstance()
|
||||||
|
.getPlusSignPattern()
|
||||||
|
.matcher(URLEncoder.encode(docName, StandardCharsets.UTF_8))
|
||||||
|
.replaceAll("%20");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Resource} backed by a {@link TempFile}. The underlying temp file is deleted when the
|
||||||
|
* response {@code InputStream} is closed — i.e. after Spring has finished writing the body. Any
|
||||||
|
* {@link IOException} during the copy is logged via {@link ClosingInputStream} and propagates
|
||||||
|
* through Spring's normal error path. Since response headers are committed before the body
|
||||||
|
* transfer begins, a mid-body failure manifests as a server-side log entry plus an aborted
|
||||||
|
* connection rather than a silently-truncated success — which is the behaviour this class was
|
||||||
|
* added to restore.
|
||||||
|
*
|
||||||
|
* <p><b>Single-use contract:</b> {@link #getInputStream()} is intended to be called once by
|
||||||
|
* Spring's {@code ResourceHttpMessageConverter} on the normal write path. After the returned
|
||||||
|
* stream is closed the backing temp file is deleted, so subsequent {@code getInputStream()}
|
||||||
|
* calls will either see a deleted file (tests that mock {@link TempFile#close()} are an
|
||||||
|
* exception) or fail at read time. Callers that need to re-read the body must copy it first.
|
||||||
|
*/
|
||||||
|
public static final class ManagedTempFileResource extends FileSystemResource {
|
||||||
|
|
||||||
|
private final TempFile tempFile;
|
||||||
|
|
||||||
|
public ManagedTempFileResource(TempFile tempFile) {
|
||||||
|
super(tempFile.getFile());
|
||||||
|
this.tempFile = tempFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
InputStream source;
|
||||||
|
try {
|
||||||
|
source = super.getInputStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Opening the input stream already failed; make sure we don't leak the temp file.
|
||||||
|
try {
|
||||||
|
tempFile.close();
|
||||||
|
} catch (Exception closeEx) {
|
||||||
|
e.addSuppressed(closeEx);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return new ClosingInputStream(source, tempFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream wrapper that deletes its backing {@link TempFile} on close. Logs — but does not
|
||||||
|
* swallow — any IOException that happens while reading the body, so upstream handlers can
|
||||||
|
* surface the failure to the client.
|
||||||
|
*/
|
||||||
|
private static final class ClosingInputStream extends FilterInputStream {
|
||||||
|
|
||||||
|
private final TempFile tempFile;
|
||||||
|
private boolean closed;
|
||||||
|
|
||||||
|
ClosingInputStream(InputStream delegate, TempFile tempFile) {
|
||||||
|
super(delegate);
|
||||||
|
this.tempFile = tempFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
try {
|
||||||
|
return super.read();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(
|
||||||
|
"Failed to read temp response body {} while streaming to client",
|
||||||
|
tempFile.getAbsolutePath(),
|
||||||
|
e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
try {
|
||||||
|
return super.read(b, off, len);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(
|
||||||
|
"Failed to read temp response body {} while streaming to client",
|
||||||
|
tempFile.getAbsolutePath(),
|
||||||
|
e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
if (closed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closed = true;
|
||||||
|
try {
|
||||||
|
super.close();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
tempFile.close();
|
||||||
|
} catch (Exception closeEx) {
|
||||||
|
log.warn(
|
||||||
|
"Failed to clean up temp file {} after streaming response",
|
||||||
|
tempFile.getAbsolutePath(),
|
||||||
|
closeEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -13,6 +16,8 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -185,4 +190,76 @@ class FileStorageTest {
|
|||||||
// Assert
|
// Assert
|
||||||
assertFalse(result);
|
assertFalse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void storeFromResource_happyPath_persistsContent() throws IOException {
|
||||||
|
// Arrange
|
||||||
|
byte[] payload = "resource-body-bytes".getBytes(StandardCharsets.UTF_8);
|
||||||
|
Resource resource = new ByteArrayResource(payload);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
String fileId = fileStorage.storeFromResource(resource, "whatever.pdf");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertNotNull(fileId);
|
||||||
|
assertTrue(Files.exists(tempDir.resolve(fileId)));
|
||||||
|
assertArrayEquals(payload, fileStorage.retrieveBytes(fileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void storeFromResource_failureCleansUpPartialFile() throws IOException {
|
||||||
|
// Arrange: a Resource whose getInputStream returns a stream that throws after
|
||||||
|
// emitting a few bytes. The finally block in storeFromResource should remove
|
||||||
|
// the partial file on disk.
|
||||||
|
byte[] head = "partial".getBytes(StandardCharsets.UTF_8);
|
||||||
|
Resource flakyResource =
|
||||||
|
new ByteArrayResource(head) {
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() {
|
||||||
|
return new InputStream() {
|
||||||
|
private int position = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (position < head.length) {
|
||||||
|
return head[position++] & 0xFF;
|
||||||
|
}
|
||||||
|
throw new IOException("simulated mid-copy read failure");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
if (position >= head.length) {
|
||||||
|
throw new IOException("simulated mid-copy read failure");
|
||||||
|
}
|
||||||
|
int toCopy = Math.min(len, head.length - position);
|
||||||
|
System.arraycopy(head, position, b, off, toCopy);
|
||||||
|
position += toCopy;
|
||||||
|
return toCopy;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Snapshot dir contents before the call so we can detect any lingering file.
|
||||||
|
long filesBefore;
|
||||||
|
try (Stream<Path> s = Files.list(tempDir)) {
|
||||||
|
filesBefore = s.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Act + Assert: IOException must propagate out — not be swallowed.
|
||||||
|
assertThrows(
|
||||||
|
IOException.class, () -> fileStorage.storeFromResource(flakyResource, "n.pdf"));
|
||||||
|
|
||||||
|
// Assert: no partial file lingers under the storage directory — the finally
|
||||||
|
// branch's deleteIfExists must have cleaned it up.
|
||||||
|
long filesAfter;
|
||||||
|
try (Stream<Path> s = Files.list(tempDir)) {
|
||||||
|
filesAfter = s.count();
|
||||||
|
}
|
||||||
|
assertEquals(
|
||||||
|
filesBefore,
|
||||||
|
filesAfter,
|
||||||
|
"partial file must be cleaned up by storeFromResource finally block");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import static org.mockito.ArgumentMatchers.any;
|
|||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.timeout;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
@@ -24,7 +26,12 @@ import org.mockito.Captor;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.http.ContentDisposition;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
@@ -180,6 +187,46 @@ class JobExecutorServiceTest {
|
|||||||
verify(spy).runJobGeneric(eq(false), any(Supplier.class), eq(customTimeout));
|
verify(spy).runJobGeneric(eq(false), any(Supplier.class), eq(customTimeout));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldPersistResponseEntityResourceBodyViaFileStorage() throws Exception {
|
||||||
|
// Given: an async job whose result is a ResponseEntity<Resource> — the new
|
||||||
|
// branch added by the stream-to-Resource migration. The executor must route
|
||||||
|
// the body through FileStorage.storeFromResource and then record the result
|
||||||
|
// via TaskManager.setFileResult with the filename/content-type extracted
|
||||||
|
// from the response headers.
|
||||||
|
byte[] payload = "resource-bytes".getBytes(StandardCharsets.UTF_8);
|
||||||
|
Resource resource = new ByteArrayResource(payload);
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_PDF);
|
||||||
|
headers.setContentDisposition(
|
||||||
|
ContentDisposition.formData().name("attachment").filename("result.pdf").build());
|
||||||
|
|
||||||
|
Supplier<Object> work = () -> new ResponseEntity<>(resource, headers, HttpStatus.OK);
|
||||||
|
|
||||||
|
when(fileStorage.storeFromResource(any(Resource.class), anyString()))
|
||||||
|
.thenReturn("stored-file-id");
|
||||||
|
|
||||||
|
// When: run the job asynchronously — processJobResult runs on the executor.
|
||||||
|
ResponseEntity<?> response = jobExecutorService.runJobGeneric(true, work);
|
||||||
|
|
||||||
|
// Then: the immediate return must be the JobResponse envelope.
|
||||||
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
assertInstanceOf(JobResponse.class, response.getBody());
|
||||||
|
|
||||||
|
// Wait for async processing and verify the Resource branch was taken —
|
||||||
|
// FileStorage.storeFromResource was invoked with the same Resource instance,
|
||||||
|
// and TaskManager.setFileResult recorded the extracted filename + content-type.
|
||||||
|
verify(fileStorage, timeout(5000)).storeFromResource(eq(resource), eq("result.pdf"));
|
||||||
|
verify(taskManager, timeout(5000))
|
||||||
|
.setFileResult(
|
||||||
|
anyString(),
|
||||||
|
eq("stored-file-id"),
|
||||||
|
eq("result.pdf"),
|
||||||
|
eq(MediaType.APPLICATION_PDF_VALUE));
|
||||||
|
verify(taskManager, timeout(5000)).setComplete(anyString());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldHandleTimeout() throws Exception {
|
void shouldHandleTimeout() throws Exception {
|
||||||
// Given
|
// Given
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.ZipSecurity;
|
import io.github.pixee.security.ZipSecurity;
|
||||||
|
|
||||||
@@ -83,9 +83,11 @@ class PDFToFileTest {
|
|||||||
pdfToFile = new PDFToFile(mockTempFileManager, mockRuntimePathConfig);
|
pdfToFile = new PDFToFile(mockTempFileManager, mockRuntimePathConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drain(ResponseEntity<StreamingResponseBody> response) throws IOException {
|
private static byte[] drain(ResponseEntity<Resource> response) throws IOException {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +102,7 @@ class PDFToFileTest {
|
|||||||
"This is not a PDF".getBytes());
|
"This is not a PDF".getBytes());
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
ResponseEntity<StreamingResponseBody> response = pdfToFile.processPdfToMarkdown(nonPdfFile);
|
ResponseEntity<Resource> response = pdfToFile.processPdfToMarkdown(nonPdfFile);
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
@@ -117,7 +119,7 @@ class PDFToFileTest {
|
|||||||
"This is not a PDF".getBytes());
|
"This is not a PDF".getBytes());
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
ResponseEntity<StreamingResponseBody> response = pdfToFile.processPdfToHtml(nonPdfFile);
|
ResponseEntity<Resource> response = pdfToFile.processPdfToHtml(nonPdfFile);
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
@@ -135,7 +137,7 @@ class PDFToFileTest {
|
|||||||
"This is not a PDF".getBytes());
|
"This is not a PDF".getBytes());
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFile.processPdfToOfficeFormat(nonPdfFile, "docx", "draw_pdf_import");
|
pdfToFile.processPdfToOfficeFormat(nonPdfFile, "docx", "draw_pdf_import");
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
@@ -154,7 +156,7 @@ class PDFToFileTest {
|
|||||||
"Fake PDF content".getBytes());
|
"Fake PDF content".getBytes());
|
||||||
|
|
||||||
// Execute with invalid format
|
// Execute with invalid format
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFile.processPdfToOfficeFormat(pdfFile, "invalid_format", "draw_pdf_import");
|
pdfToFile.processPdfToOfficeFormat(pdfFile, "invalid_format", "draw_pdf_import");
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
@@ -205,8 +207,7 @@ class PDFToFileTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Execute the method
|
// Execute the method
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = pdfToFile.processPdfToMarkdown(pdfFile);
|
||||||
pdfToFile.processPdfToMarkdown(pdfFile);
|
|
||||||
|
|
||||||
// Verify - should now return a ZIP file instead of plain markdown
|
// Verify - should now return a ZIP file instead of plain markdown
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -298,8 +299,7 @@ class PDFToFileTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Execute the method
|
// Execute the method
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = pdfToFile.processPdfToMarkdown(pdfFile);
|
||||||
pdfToFile.processPdfToMarkdown(pdfFile);
|
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -377,7 +377,7 @@ class PDFToFileTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Execute the method
|
// Execute the method
|
||||||
ResponseEntity<StreamingResponseBody> response = pdfToFile.processPdfToHtml(pdfFile);
|
ResponseEntity<Resource> response = pdfToFile.processPdfToHtml(pdfFile);
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -463,7 +463,7 @@ class PDFToFileTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Execute the method with docx format
|
// Execute the method with docx format
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFile.processPdfToOfficeFormat(pdfFile, "docx", "draw_pdf_import");
|
pdfToFile.processPdfToOfficeFormat(pdfFile, "docx", "draw_pdf_import");
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
@@ -535,7 +535,7 @@ class PDFToFileTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Execute the method with ODP format
|
// Execute the method with ODP format
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFile.processPdfToOfficeFormat(pdfFile, "odp", "draw_pdf_import");
|
pdfToFile.processPdfToOfficeFormat(pdfFile, "odp", "draw_pdf_import");
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
@@ -620,7 +620,7 @@ class PDFToFileTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Execute the method with text format
|
// Execute the method with text format
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFile.processPdfToOfficeFormat(pdfFile, "txt:Text", "draw_pdf_import");
|
pdfToFile.processPdfToOfficeFormat(pdfFile, "txt:Text", "draw_pdf_import");
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
@@ -679,7 +679,7 @@ class PDFToFileTest {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Execute the method
|
// Execute the method
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFile.processPdfToOfficeFormat(pdfFile, "docx", "draw_pdf_import");
|
pdfToFile.processPdfToOfficeFormat(pdfFile, "docx", "draw_pdf_import");
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
@@ -726,7 +726,7 @@ class PDFToFileTest {
|
|||||||
return mockExecutorResult;
|
return mockExecutorResult;
|
||||||
});
|
});
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFileWithUno.processPdfToOfficeFormat(pdfFile, "docx", "writer_pdf_import");
|
pdfToFileWithUno.processPdfToOfficeFormat(pdfFile, "docx", "writer_pdf_import");
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -790,7 +790,7 @@ class PDFToFileTest {
|
|||||||
return mockExecutorResult;
|
return mockExecutorResult;
|
||||||
});
|
});
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
pdfToFileWithUno.processPdfToOfficeFormat(pdfFile, "docx", "writer_pdf_import");
|
pdfToFileWithUno.processPdfToOfficeFormat(pdfFile, "docx", "writer_pdf_import");
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
|||||||
@@ -3,17 +3,39 @@ package stirling.software.common.util;
|
|||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import stirling.software.common.model.ApplicationProperties;
|
||||||
|
|
||||||
class WebResponseUtilsTest {
|
class WebResponseUtilsTest {
|
||||||
|
|
||||||
|
@TempDir Path tempDir;
|
||||||
|
|
||||||
|
private TempFileManager tempFileManager;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUpTempFileManager() {
|
||||||
|
TempFileRegistry registry = new TempFileRegistry();
|
||||||
|
ApplicationProperties applicationProperties = new ApplicationProperties();
|
||||||
|
applicationProperties.getSystem().getTempFileManagement().setBaseTmpDir(tempDir.toString());
|
||||||
|
applicationProperties.getSystem().getTempFileManagement().setPrefix("wru-test-");
|
||||||
|
tempFileManager = new TempFileManager(registry, applicationProperties);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBytesToWebResponse_defaultMediaType() throws IOException {
|
void testBytesToWebResponse_defaultMediaType() throws IOException {
|
||||||
byte[] data = "test content".getBytes(StandardCharsets.UTF_8);
|
byte[] data = "test content".getBytes(StandardCharsets.UTF_8);
|
||||||
@@ -91,4 +113,87 @@ class WebResponseUtilsTest {
|
|||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertEquals(0, response.getHeaders().getContentLength());
|
assertEquals(0, response.getHeaders().getContentLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void managedTempFileResource_happyPathDeletesBackingFile() throws IOException {
|
||||||
|
// Create a real managed temp file on disk and populate it.
|
||||||
|
TempFile tempFile = tempFileManager.createManagedTempFile(".pdf");
|
||||||
|
byte[] payload = "fully-readable-pdf-body".getBytes(StandardCharsets.UTF_8);
|
||||||
|
Files.write(tempFile.getPath(), payload);
|
||||||
|
File backing = tempFile.getFile();
|
||||||
|
assertTrue(backing.exists(), "precondition: backing file should exist");
|
||||||
|
|
||||||
|
WebResponseUtils.ManagedTempFileResource resource =
|
||||||
|
new WebResponseUtils.ManagedTempFileResource(tempFile);
|
||||||
|
|
||||||
|
byte[] readBack;
|
||||||
|
try (InputStream in = resource.getInputStream()) {
|
||||||
|
readBack = in.readAllBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertArrayEquals(payload, readBack, "stream should deliver the original bytes");
|
||||||
|
assertFalse(
|
||||||
|
backing.exists(),
|
||||||
|
"backing temp file must be deleted once the response stream is closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void closingInputStream_propagatesReadFailure() throws IOException {
|
||||||
|
// ManagedTempFileResource is final, so we can't swap in a mock underlying stream.
|
||||||
|
// Instead: open the resource's stream, close the inner FileInputStream early
|
||||||
|
// (by closing the outer stream once), then confirm reading the now-closed stream
|
||||||
|
// throws — exercising ClosingInputStream's read() catch/log/rethrow path. Finally
|
||||||
|
// confirm the temp file is still cleaned up on close().
|
||||||
|
TempFile tempFile = tempFileManager.createManagedTempFile(".pdf");
|
||||||
|
Files.write(tempFile.getPath(), "some-bytes".getBytes(StandardCharsets.UTF_8));
|
||||||
|
File backing = tempFile.getFile();
|
||||||
|
assertTrue(backing.exists());
|
||||||
|
|
||||||
|
WebResponseUtils.ManagedTempFileResource resource =
|
||||||
|
new WebResponseUtils.ManagedTempFileResource(tempFile);
|
||||||
|
|
||||||
|
InputStream in = resource.getInputStream();
|
||||||
|
// Pre-close the underlying stream to guarantee read() throws.
|
||||||
|
in.close();
|
||||||
|
// After close, the temp file has been deleted already.
|
||||||
|
assertFalse(
|
||||||
|
backing.exists(),
|
||||||
|
"backing file is deleted on first close — precondition for read assertion");
|
||||||
|
|
||||||
|
// Any attempt to read from the already-closed stream must throw IOException
|
||||||
|
// (not silently return -1). This exercises the ClosingInputStream.read() path
|
||||||
|
// that logs and rethrows.
|
||||||
|
IOException ioex = assertThrows(IOException.class, in::read);
|
||||||
|
assertNotNull(ioex);
|
||||||
|
|
||||||
|
// close() is idempotent — a second call must not throw.
|
||||||
|
assertDoesNotThrow(in::close);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void managedTempFileResource_openFailureCleansUp() throws IOException {
|
||||||
|
// Arrange: build a TempFile whose backing file is deleted out from under it so
|
||||||
|
// super.getInputStream() throws on open. Instrument close() with an AtomicBoolean
|
||||||
|
// hook to confirm the cleanup path ran.
|
||||||
|
AtomicBoolean closed = new AtomicBoolean(false);
|
||||||
|
TempFile spying =
|
||||||
|
new TempFile(tempFileManager, ".pdf") {
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
closed.set(true);
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assertTrue(
|
||||||
|
spying.getFile().delete(),
|
||||||
|
"precondition: delete backing so super.getInputStream() fails");
|
||||||
|
|
||||||
|
WebResponseUtils.ManagedTempFileResource resource =
|
||||||
|
new WebResponseUtils.ManagedTempFileResource(spying);
|
||||||
|
|
||||||
|
assertThrows(IOException.class, resource::getInputStream);
|
||||||
|
assertTrue(
|
||||||
|
closed.get(),
|
||||||
|
"tempFile.close() must run when super.getInputStream() fails on open");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -12,13 +12,13 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -51,7 +51,7 @@ public class BookletImpositionController {
|
|||||||
"This operation combines page reordering for booklet printing with multi-page layout. "
|
"This operation combines page reordering for booklet printing with multi-page layout. "
|
||||||
+ "It rearranges pages in the correct order for booklet printing and places multiple pages "
|
+ "It rearranges pages in the correct order for booklet printing and places multiple pages "
|
||||||
+ "on each sheet for proper folding and binding. Input:PDF Output:PDF Type:SISO")
|
+ "on each sheet for proper folding and binding. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> createBookletImposition(
|
public ResponseEntity<Resource> createBookletImposition(
|
||||||
@ModelAttribute BookletImpositionRequest request) throws IOException {
|
@ModelAttribute BookletImpositionRequest request) throws IOException {
|
||||||
|
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ public class CropController {
|
|||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file and crops it according to the given"
|
"This operation takes an input PDF file and crops it according to the given"
|
||||||
+ " coordinates. Input:PDF Output:PDF Type:SISO")
|
+ " coordinates. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> cropPdf(@ModelAttribute CropPdfForm request)
|
public ResponseEntity<Resource> cropPdf(@ModelAttribute CropPdfForm request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (request.isAutoCrop()) {
|
if (request.isAutoCrop()) {
|
||||||
return cropWithAutomaticDetection(request);
|
return cropWithAutomaticDetection(request);
|
||||||
@@ -153,8 +153,8 @@ public class CropController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> cropWithAutomaticDetection(
|
private ResponseEntity<Resource> cropWithAutomaticDetection(@ModelAttribute CropPdfForm request)
|
||||||
@ModelAttribute CropPdfForm request) throws IOException {
|
throws IOException {
|
||||||
try (PDDocument sourceDocument = pdfDocumentFactory.load(request)) {
|
try (PDDocument sourceDocument = pdfDocumentFactory.load(request)) {
|
||||||
|
|
||||||
try (PDDocument newDocument =
|
try (PDDocument newDocument =
|
||||||
@@ -207,8 +207,8 @@ public class CropController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> cropWithPDFBox(
|
private ResponseEntity<Resource> cropWithPDFBox(@ModelAttribute CropPdfForm request)
|
||||||
@ModelAttribute CropPdfForm request) throws IOException {
|
throws IOException {
|
||||||
try (PDDocument sourceDocument = pdfDocumentFactory.load(request)) {
|
try (PDDocument sourceDocument = pdfDocumentFactory.load(request)) {
|
||||||
|
|
||||||
try (PDDocument newDocument =
|
try (PDDocument newDocument =
|
||||||
@@ -263,8 +263,8 @@ public class CropController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> cropWithGhostscript(
|
private ResponseEntity<Resource> cropWithGhostscript(@ModelAttribute CropPdfForm request)
|
||||||
@ModelAttribute CropPdfForm request) throws IOException {
|
throws IOException {
|
||||||
TempFile tempInputFile = null;
|
TempFile tempInputFile = null;
|
||||||
TempFile tempOutputFile = null;
|
TempFile tempOutputFile = null;
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ public class CropController {
|
|||||||
processExecutor.runCommandWithOutputHandling(command);
|
processExecutor.runCommandWithOutputHandling(command);
|
||||||
|
|
||||||
TempFile out = tempOutputFile;
|
TempFile out = tempOutputFile;
|
||||||
tempOutputFile = null; // ownership transferred to StreamingResponseBody
|
tempOutputFile = null; // ownership transferred to response Resource
|
||||||
return WebResponseUtils.pdfFileToWebResponse(
|
return WebResponseUtils.pdfFileToWebResponse(
|
||||||
out,
|
out,
|
||||||
GeneralUtils.generateFilename(
|
GeneralUtils.generateFilename(
|
||||||
|
|||||||
+2
-2
@@ -9,11 +9,11 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
|
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ public class EditTableOfContentsController {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Edit Table of Contents",
|
summary = "Edit Table of Contents",
|
||||||
description = "Add or edit bookmarks/table of contents in a PDF document.")
|
description = "Add or edit bookmarks/table of contents in a PDF document.")
|
||||||
public ResponseEntity<StreamingResponseBody> editTableOfContents(
|
public ResponseEntity<Resource> editTableOfContents(
|
||||||
@ModelAttribute EditTableOfContentsRequest request) throws Exception {
|
@ModelAttribute EditTableOfContentsRequest request) throws Exception {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
|||||||
import org.apache.xmpbox.XMPMetadata;
|
import org.apache.xmpbox.XMPMetadata;
|
||||||
import org.apache.xmpbox.schema.XMPBasicSchema;
|
import org.apache.xmpbox.schema.XMPBasicSchema;
|
||||||
import org.apache.xmpbox.xml.DomXmpParser;
|
import org.apache.xmpbox.xml.DomXmpParser;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -279,7 +279,7 @@ public class MergeController {
|
|||||||
"This endpoint merges multiple PDF files into a single PDF file. The merged"
|
"This endpoint merges multiple PDF files into a single PDF file. The merged"
|
||||||
+ " file will contain all pages from the input files in the order they were"
|
+ " file will contain all pages from the input files in the order they were"
|
||||||
+ " provided. Input:PDF Output:PDF Type:MISO")
|
+ " provided. Input:PDF Output:PDF Type:MISO")
|
||||||
public ResponseEntity<StreamingResponseBody> mergePdfs(
|
public ResponseEntity<Resource> mergePdfs(
|
||||||
@ModelAttribute MergePdfsRequest request,
|
@ModelAttribute MergePdfsRequest request,
|
||||||
@RequestParam(value = "fileOrder", required = false) String fileOrder)
|
@RequestParam(value = "fileOrder", required = false) String fileOrder)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|||||||
+2
-2
@@ -10,11 +10,11 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ public class MultiPageLayoutController {
|
|||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file and the number of pages to merge into a"
|
"This operation takes an input PDF file and the number of pages to merge into a"
|
||||||
+ " single sheet in the output PDF file. Input:PDF Output:PDF Type:SISO")
|
+ " single sheet in the output PDF file. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> mergeMultiplePagesIntoOne(
|
public ResponseEntity<Resource> mergeMultiplePagesIntoOne(
|
||||||
@ModelAttribute MergeMultiplePagesRequest request) throws IOException {
|
@ModelAttribute MergeMultiplePagesRequest request) throws IOException {
|
||||||
|
|
||||||
int MAX_PAGES = 100000;
|
int MAX_PAGES = 100000;
|
||||||
|
|||||||
+4
-4
@@ -11,11 +11,11 @@ import java.util.Map;
|
|||||||
import org.apache.pdfbox.Loader;
|
import org.apache.pdfbox.Loader;
|
||||||
import org.apache.pdfbox.multipdf.Overlay;
|
import org.apache.pdfbox.multipdf.Overlay;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -46,8 +46,8 @@ public class PdfOverlayController {
|
|||||||
description =
|
description =
|
||||||
"Overlay PDF files onto a base PDF with different modes: Sequential,"
|
"Overlay PDF files onto a base PDF with different modes: Sequential,"
|
||||||
+ " Interleaved, or Fixed Repeat. Input:PDF Output:PDF Type:MIMO")
|
+ " Interleaved, or Fixed Repeat. Input:PDF Output:PDF Type:MIMO")
|
||||||
public ResponseEntity<StreamingResponseBody> overlayPdfs(
|
public ResponseEntity<Resource> overlayPdfs(@ModelAttribute OverlayPdfsRequest request)
|
||||||
@ModelAttribute OverlayPdfsRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile baseFile = request.getFileInput();
|
MultipartFile baseFile = request.getFileInput();
|
||||||
int overlayPos = request.getOverlayPosition();
|
int overlayPos = request.getOverlayPosition();
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ public class PdfOverlayController {
|
|||||||
baseFile.getOriginalFilename(), "_overlayed.pdf");
|
baseFile.getOriginalFilename(), "_overlayed.pdf");
|
||||||
|
|
||||||
TempFile out = tempOut;
|
TempFile out = tempOut;
|
||||||
tempOut = null; // ownership transferred to StreamingResponseBody
|
tempOut = null; // ownership transferred to response Resource
|
||||||
return WebResponseUtils.pdfFileToWebResponse(out, outputFilename);
|
return WebResponseUtils.pdfFileToWebResponse(out, outputFilename);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
+2
-2
@@ -14,10 +14,10 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ public class PosterPdfController {
|
|||||||
+ "suitable for printing on standard paper sizes (e.g., A4, Letter). "
|
+ "suitable for printing on standard paper sizes (e.g., A4, Letter). "
|
||||||
+ "Divides each page into a grid of smaller pages using Apache PDFBox. "
|
+ "Divides each page into a grid of smaller pages using Apache PDFBox. "
|
||||||
+ "Input: PDF Output: ZIP-PDF Type: SISO")
|
+ "Input: PDF Output: ZIP-PDF Type: SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> posterPdf(@ModelAttribute PosterPdfRequest request)
|
public ResponseEntity<Resource> posterPdf(@ModelAttribute PosterPdfRequest request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
log.debug("Starting PDF poster split process with request: {}", request);
|
log.debug("Starting PDF poster split process with request: {}", request);
|
||||||
|
|||||||
+5
-5
@@ -8,11 +8,11 @@ import java.util.Locale;
|
|||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -47,8 +47,8 @@ public class RearrangePagesPDFController {
|
|||||||
"This endpoint removes specified pages from a given PDF file. Users can provide"
|
"This endpoint removes specified pages from a given PDF file. Users can provide"
|
||||||
+ " a comma-separated list of page numbers or ranges to delete. Input:PDF"
|
+ " a comma-separated list of page numbers or ranges to delete. Input:PDF"
|
||||||
+ " Output:PDF Type:SISO")
|
+ " Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> deletePages(
|
public ResponseEntity<Resource> deletePages(@ModelAttribute PDFWithPageNums request)
|
||||||
@ModelAttribute PDFWithPageNums request) throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
String pagesToDelete = request.getPageNumbers();
|
String pagesToDelete = request.getPageNumbers();
|
||||||
@@ -228,8 +228,8 @@ public class RearrangePagesPDFController {
|
|||||||
+ " order or custom mode. Users can provide a page order as a"
|
+ " order or custom mode. Users can provide a page order as a"
|
||||||
+ " comma-separated list of page numbers or page ranges, or a custom mode."
|
+ " comma-separated list of page numbers or page ranges, or a custom mode."
|
||||||
+ " Input:PDF Output:PDF")
|
+ " Input:PDF Output:PDF")
|
||||||
public ResponseEntity<StreamingResponseBody> rearrangePages(
|
public ResponseEntity<Resource> rearrangePages(@ModelAttribute RearrangePagesRequest request)
|
||||||
@ModelAttribute RearrangePagesRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
String pageOrder = request.getPageNumbers();
|
String pageOrder = request.getPageNumbers();
|
||||||
String sortType = request.getCustomMode();
|
String sortType = request.getCustomMode();
|
||||||
|
|||||||
+2
-2
@@ -5,11 +5,11 @@ import java.io.IOException;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public class RotationController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint rotates a given PDF file by a specified angle. The angle must be"
|
"This endpoint rotates a given PDF file by a specified angle. The angle must be"
|
||||||
+ " a multiple of 90. Input:PDF Output:PDF Type:SISO")
|
+ " a multiple of 90. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> rotatePDF(@ModelAttribute RotatePDFRequest request)
|
public ResponseEntity<Resource> rotatePDF(@ModelAttribute RotatePDFRequest request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
Integer angle = request.getAngle();
|
Integer angle = request.getAngle();
|
||||||
|
|||||||
+3
-3
@@ -11,11 +11,11 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -120,8 +120,8 @@ public class ScalePagesController {
|
|||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file and the size to scale the pages to in"
|
"This operation takes an input PDF file and the size to scale the pages to in"
|
||||||
+ " the output PDF file. Input:PDF Output:PDF Type:SISO")
|
+ " the output PDF file. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> scalePages(
|
public ResponseEntity<Resource> scalePages(@ModelAttribute ScalePagesRequest request)
|
||||||
@ModelAttribute ScalePagesRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
String targetPDRectangle = request.getPageSize();
|
String targetPDRectangle = request.getPageSize();
|
||||||
float scaleFactor = request.getScaleFactor();
|
float scaleFactor = request.getScaleFactor();
|
||||||
|
|||||||
+2
-2
@@ -9,11 +9,11 @@ import java.util.zip.ZipEntry;
|
|||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public class SplitPDFController {
|
|||||||
+ " specified page numbers or ranges. Users can specify pages using"
|
+ " specified page numbers or ranges. Users can specify pages using"
|
||||||
+ " individual numbers, ranges, or 'all' for every page. Input:PDF"
|
+ " individual numbers, ranges, or 'all' for every page. Input:PDF"
|
||||||
+ " Output:PDF Type:SIMO")
|
+ " Output:PDF Type:SIMO")
|
||||||
public ResponseEntity<StreamingResponseBody> splitPdf(@ModelAttribute SplitPagesRequest request)
|
public ResponseEntity<Resource> splitPdf(@ModelAttribute SplitPagesRequest request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|||||||
+3
-3
@@ -11,11 +11,11 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
|
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -127,8 +127,8 @@ public class SplitPdfByChaptersController {
|
|||||||
description =
|
description =
|
||||||
"Splits a PDF into chapters and returns a ZIP file. Input:PDF Output:ZIP-PDF"
|
"Splits a PDF into chapters and returns a ZIP file. Input:PDF Output:ZIP-PDF"
|
||||||
+ " Type:SISO")
|
+ " Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> splitPdf(
|
public ResponseEntity<Resource> splitPdf(@ModelAttribute SplitPdfByChaptersRequest request)
|
||||||
@ModelAttribute SplitPdfByChaptersRequest request) throws Exception {
|
throws Exception {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|
||||||
boolean includeMetadata = Boolean.TRUE.equals(request.getIncludeMetadata());
|
boolean includeMetadata = Boolean.TRUE.equals(request.getIncludeMetadata());
|
||||||
|
|||||||
+2
-2
@@ -15,11 +15,11 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream.AppendMode;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ public class SplitPdfBySectionsController {
|
|||||||
+ " which page to split, and how to split"
|
+ " which page to split, and how to split"
|
||||||
+ " ( halves, thirds, quarters, etc.), both vertically and horizontally."
|
+ " ( halves, thirds, quarters, etc.), both vertically and horizontally."
|
||||||
+ " Input:PDF Output:ZIP-PDF Type:SISO")
|
+ " Input:PDF Output:ZIP-PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> splitPdf(
|
public ResponseEntity<Resource> splitPdf(
|
||||||
@Valid @ModelAttribute SplitPdfBySectionsRequest request) throws Exception {
|
@Valid @ModelAttribute SplitPdfBySectionsRequest request) throws Exception {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
String pageNumbers = request.getPageNumbers();
|
String pageNumbers = request.getPageNumbers();
|
||||||
|
|||||||
+2
-2
@@ -8,11 +8,11 @@ import java.util.zip.ZipOutputStream;
|
|||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ public class SplitPdfBySizeController {
|
|||||||
+ " if 10MB and each page is 1MB and you enter 2MB then 5 docs each 2MB"
|
+ " if 10MB and each page is 1MB and you enter 2MB then 5 docs each 2MB"
|
||||||
+ " (rounded so that it accepts 1.9MB but not 2.1MB) Input:PDF"
|
+ " (rounded so that it accepts 1.9MB but not 2.1MB) Input:PDF"
|
||||||
+ " Output:ZIP-PDF Type:SISO")
|
+ " Output:ZIP-PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> autoSplitPdf(
|
public ResponseEntity<Resource> autoSplitPdf(
|
||||||
@ModelAttribute SplitPdfBySizeOrCountRequest request) throws Exception {
|
@ModelAttribute SplitPdfBySizeOrCountRequest request) throws Exception {
|
||||||
|
|
||||||
log.debug("Starting PDF split process with request: {}", request);
|
log.debug("Starting PDF split process with request: {}", request);
|
||||||
|
|||||||
+2
-2
@@ -8,10 +8,10 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ public class ToSinglePageController {
|
|||||||
+ " document. The width of the single page will be same as the input's"
|
+ " document. The width of the single page will be same as the input's"
|
||||||
+ " width, but the height will be the sum of all the pages' heights."
|
+ " width, but the height will be the sum of all the pages' heights."
|
||||||
+ " Input:PDF Output:PDF Type:SISO")
|
+ " Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> pdfToSinglePage(@ModelAttribute PDFFile request)
|
public ResponseEntity<Resource> pdfToSinglePage(@ModelAttribute PDFFile request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
// Load the source document
|
// Load the source document
|
||||||
|
|||||||
+3
-3
@@ -12,11 +12,11 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -62,7 +62,7 @@ public class ConvertEbookToPDFController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts common eBook formats (EPUB, MOBI, AZW3, FB2, TXT, DOCX)"
|
"This endpoint converts common eBook formats (EPUB, MOBI, AZW3, FB2, TXT, DOCX)"
|
||||||
+ " to PDF using Calibre. Input:BOOK Output:PDF Type:SISO")
|
+ " to PDF using Calibre. Input:BOOK Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertEbookToPdf(
|
public ResponseEntity<Resource> convertEbookToPdf(
|
||||||
@ModelAttribute ConvertEbookToPdfRequest request) throws Exception {
|
@ModelAttribute ConvertEbookToPdfRequest request) throws Exception {
|
||||||
if (!isCalibreEnabled()) {
|
if (!isCalibreEnabled()) {
|
||||||
throw new IllegalStateException("Calibre support is disabled");
|
throw new IllegalStateException("Calibre support is disabled");
|
||||||
@@ -162,7 +162,7 @@ public class ConvertEbookToPDFController {
|
|||||||
document.save(tempOut.getFile());
|
document.save(tempOut.getFile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
WebResponseUtils.pdfFileToWebResponse(tempOut, outputFilename);
|
WebResponseUtils.pdfFileToWebResponse(tempOut, outputFilename);
|
||||||
tempOut = null;
|
tempOut = null;
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
+7
-10
@@ -6,12 +6,13 @@ import java.nio.file.Files;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
import org.springframework.web.util.HtmlUtils;
|
import org.springframework.web.util.HtmlUtils;
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
@@ -51,8 +52,7 @@ public class ConvertEmlToPDF {
|
|||||||
+ " with extensive customization options. Features include font settings,"
|
+ " with extensive customization options. Features include font settings,"
|
||||||
+ " image constraints, display modes, attachment handling, and HTML debug"
|
+ " image constraints, display modes, attachment handling, and HTML debug"
|
||||||
+ " output. Input: EML or MSG file, Output: PDF or HTML file. Type: SISO")
|
+ " output. Input: EML or MSG file, Output: PDF or HTML file. Type: SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertEmlToPdf(
|
public ResponseEntity<Resource> convertEmlToPdf(@ModelAttribute EmlToPdfRequest request) {
|
||||||
@ModelAttribute EmlToPdfRequest request) {
|
|
||||||
|
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
String originalFilename = inputFile.getOriginalFilename();
|
String originalFilename = inputFile.getOriginalFilename();
|
||||||
@@ -159,14 +159,11 @@ public class ConvertEmlToPDF {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> errorResponse(HttpStatus status, String message) {
|
private ResponseEntity<Resource> errorResponse(HttpStatus status, String message) {
|
||||||
byte[] body = message.getBytes(StandardCharsets.UTF_8);
|
byte[] body = message.getBytes(StandardCharsets.UTF_8);
|
||||||
StreamingResponseBody streaming =
|
return ResponseEntity.status(status)
|
||||||
os -> {
|
.contentLength(body.length)
|
||||||
os.write(body);
|
.body(new ByteArrayResource(body));
|
||||||
os.flush();
|
|
||||||
};
|
|
||||||
return ResponseEntity.status(status).body(streaming);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NotNull String buildErrorMessage(Exception e, String originalFilename) {
|
private static @NotNull String buildErrorMessage(Exception e, String originalFilename) {
|
||||||
|
|||||||
+2
-2
@@ -2,11 +2,11 @@ package stirling.software.SPDF.controller.api.converters;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -40,7 +40,7 @@ public class ConvertHtmlToPDF {
|
|||||||
description =
|
description =
|
||||||
"This endpoint takes an HTML or ZIP file input and converts it to a PDF format."
|
"This endpoint takes an HTML or ZIP file input and converts it to a PDF format."
|
||||||
+ " Input:HTML Output:PDF Type:SISO")
|
+ " Input:HTML Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> HtmlToPdf(@ModelAttribute HTMLToPdfRequest request)
|
public ResponseEntity<Resource> HtmlToPdf(@ModelAttribute HTMLToPdfRequest request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -18,11 +18,11 @@ import org.apache.commons.io.FileUtils;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.rendering.ImageType;
|
import org.apache.pdfbox.rendering.ImageType;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -274,8 +274,8 @@ public class ConvertImgPDFController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts a CBZ (ZIP) comic book archive to a PDF file. "
|
"This endpoint converts a CBZ (ZIP) comic book archive to a PDF file. "
|
||||||
+ "Input:CBZ Output:PDF Type:SISO")
|
+ "Input:CBZ Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertCbzToPdf(
|
public ResponseEntity<Resource> convertCbzToPdf(@ModelAttribute ConvertCbzToPdfRequest request)
|
||||||
@ModelAttribute ConvertCbzToPdfRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
boolean optimizeForEbook = request.isOptimizeForEbook();
|
boolean optimizeForEbook = request.isOptimizeForEbook();
|
||||||
|
|
||||||
@@ -300,8 +300,8 @@ public class ConvertImgPDFController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts a PDF file to a CBZ (ZIP) comic book archive. "
|
"This endpoint converts a PDF file to a CBZ (ZIP) comic book archive. "
|
||||||
+ "Input:PDF Output:CBZ Type:SISO")
|
+ "Input:PDF Output:CBZ Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertPdfToCbz(
|
public ResponseEntity<Resource> convertPdfToCbz(@ModelAttribute ConvertPdfToCbzRequest request)
|
||||||
@ModelAttribute ConvertPdfToCbzRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
int dpi = request.getDpi();
|
int dpi = request.getDpi();
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -11,11 +11,11 @@ import org.commonmark.node.Node;
|
|||||||
import org.commonmark.parser.Parser;
|
import org.commonmark.parser.Parser;
|
||||||
import org.commonmark.renderer.html.AttributeProvider;
|
import org.commonmark.renderer.html.AttributeProvider;
|
||||||
import org.commonmark.renderer.html.HtmlRenderer;
|
import org.commonmark.renderer.html.HtmlRenderer;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -48,8 +48,8 @@ public class ConvertMarkdownToPdf {
|
|||||||
description =
|
description =
|
||||||
"This endpoint takes a Markdown file or ZIP (containing Markdown + images) input, converts it to HTML, and then to"
|
"This endpoint takes a Markdown file or ZIP (containing Markdown + images) input, converts it to HTML, and then to"
|
||||||
+ " PDF format. Input:MARKDOWN Output:PDF Type:SISO")
|
+ " PDF format. Input:MARKDOWN Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> markdownToPdf(
|
public ResponseEntity<Resource> markdownToPdf(@ModelAttribute GeneralFile generalFile)
|
||||||
@ModelAttribute GeneralFile generalFile) throws Exception {
|
throws Exception {
|
||||||
MultipartFile fileInput = generalFile.getFileInput();
|
MultipartFile fileInput = generalFile.getFileInput();
|
||||||
|
|
||||||
if (fileInput == null) {
|
if (fileInput == null) {
|
||||||
|
|||||||
+4
-4
@@ -13,11 +13,11 @@ import java.util.Locale;
|
|||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -206,8 +206,8 @@ public class ConvertOfficeController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts a given file to a PDF using LibreOffice API Input:ANY"
|
"This endpoint converts a given file to a PDF using LibreOffice API Input:ANY"
|
||||||
+ " Output:PDF Type:SISO")
|
+ " Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> processFileToPDF(
|
public ResponseEntity<Resource> processFileToPDF(@ModelAttribute GeneralFile generalFile)
|
||||||
@ModelAttribute GeneralFile generalFile) throws Exception {
|
throws Exception {
|
||||||
MultipartFile inputFile = generalFile.getFileInput();
|
MultipartFile inputFile = generalFile.getFileInput();
|
||||||
// unused but can start server instance if startup time is to long
|
// unused but can start server instance if startup time is to long
|
||||||
// LibreOfficeListener.getInstance().start();
|
// LibreOfficeListener.getInstance().start();
|
||||||
@@ -223,7 +223,7 @@ public class ConvertOfficeController {
|
|||||||
String filename =
|
String filename =
|
||||||
GeneralUtils.generateFilename(
|
GeneralUtils.generateFilename(
|
||||||
inputFile.getOriginalFilename(), "_convertedToPDF.pdf");
|
inputFile.getOriginalFilename(), "_convertedToPDF.pdf");
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
WebResponseUtils.pdfFileToWebResponse(tempOut, filename);
|
WebResponseUtils.pdfFileToWebResponse(tempOut, filename);
|
||||||
tempOut = null;
|
tempOut = null;
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
+2
-2
@@ -9,11 +9,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -87,7 +87,7 @@ public class ConvertPDFToEpubController {
|
|||||||
description =
|
description =
|
||||||
"Convert a PDF file to a high-quality EPUB or AZW3 ebook using Calibre. Input:PDF"
|
"Convert a PDF file to a high-quality EPUB or AZW3 ebook using Calibre. Input:PDF"
|
||||||
+ " Output:EPUB/AZW3 Type:SISO")
|
+ " Output:EPUB/AZW3 Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertPdfToEpub(
|
public ResponseEntity<Resource> convertPdfToEpub(
|
||||||
@ModelAttribute ConvertPdfToEpubRequest request) throws Exception {
|
@ModelAttribute ConvertPdfToEpubRequest request) throws Exception {
|
||||||
|
|
||||||
if (!endpointConfiguration.isGroupEnabled(CALIBRE_GROUP)) {
|
if (!endpointConfiguration.isGroupEnabled(CALIBRE_GROUP)) {
|
||||||
|
|||||||
+2
-2
@@ -12,10 +12,10 @@ import org.apache.poi.ss.usermodel.Sheet;
|
|||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.apache.poi.ss.util.WorkbookUtil;
|
import org.apache.poi.ss.util.WorkbookUtil;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ public class ConvertPDFToExcelController {
|
|||||||
description =
|
description =
|
||||||
"Extracts tabular data from each page of a PDF and writes it into an Excel"
|
"Extracts tabular data from each page of a PDF and writes it into an Excel"
|
||||||
+ " workbook, one sheet per table. Input:PDF Output:XLSX Type:SISO")
|
+ " workbook, one sheet per table. Input:PDF Output:XLSX Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> pdfToExcel(@ModelAttribute PDFWithPageNums request)
|
public ResponseEntity<Resource> pdfToExcel(@ModelAttribute PDFWithPageNums request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
String baseName =
|
String baseName =
|
||||||
GeneralUtils.removeExtension(request.getFileInput().getOriginalFilename());
|
GeneralUtils.removeExtension(request.getFileInput().getOriginalFilename());
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ public class ConvertPDFToHtml {
|
|||||||
summary = "Convert PDF to HTML",
|
summary = "Convert PDF to HTML",
|
||||||
description =
|
description =
|
||||||
"This endpoint converts a PDF file to HTML format. Input:PDF Output:HTML Type:SISO")
|
"This endpoint converts a PDF file to HTML format. Input:PDF Output:HTML Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToHTML(@ModelAttribute PDFFile file)
|
public ResponseEntity<Resource> processPdfToHTML(@ModelAttribute PDFFile file)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile inputFile = file.getFileInput();
|
MultipartFile inputFile = file.getFileInput();
|
||||||
PDFToFile pdfToFile = new PDFToFile(tempFileManager, runtimePathConfig);
|
PDFToFile pdfToFile = new PDFToFile(tempFileManager, runtimePathConfig);
|
||||||
|
|||||||
+6
-7
@@ -6,11 +6,11 @@ import java.nio.file.Files;
|
|||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.text.PDFTextStripper;
|
import org.apache.pdfbox.text.PDFTextStripper;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ public class ConvertPDFToOffice {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts a given PDF file to a Presentation format. Input:PDF"
|
"This endpoint converts a given PDF file to a Presentation format. Input:PDF"
|
||||||
+ " Output:PPT Type:SISO")
|
+ " Output:PPT Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToPresentation(
|
public ResponseEntity<Resource> processPdfToPresentation(
|
||||||
@ModelAttribute PdfToPresentationRequest request)
|
@ModelAttribute PdfToPresentationRequest request)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
@@ -59,7 +59,7 @@ public class ConvertPDFToOffice {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts a given PDF file to Text or RTF format. Input:PDF"
|
"This endpoint converts a given PDF file to Text or RTF format. Input:PDF"
|
||||||
+ " Output:TXT Type:SISO")
|
+ " Output:TXT Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToRTForTXT(
|
public ResponseEntity<Resource> processPdfToRTForTXT(
|
||||||
@ModelAttribute PdfToTextOrRTFRequest request)
|
@ModelAttribute PdfToTextOrRTFRequest request)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
@@ -89,8 +89,8 @@ public class ConvertPDFToOffice {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts a given PDF file to a Word document format. Input:PDF"
|
"This endpoint converts a given PDF file to a Word document format. Input:PDF"
|
||||||
+ " Output:WORD Type:SISO")
|
+ " Output:WORD Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToWord(
|
public ResponseEntity<Resource> processPdfToWord(@ModelAttribute PdfToWordRequest request)
|
||||||
@ModelAttribute PdfToWordRequest request) throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
String outputFormat = request.getOutputFormat();
|
String outputFormat = request.getOutputFormat();
|
||||||
PDFToFile pdfToFile = new PDFToFile(tempFileManager, runtimePathConfig);
|
PDFToFile pdfToFile = new PDFToFile(tempFileManager, runtimePathConfig);
|
||||||
@@ -103,8 +103,7 @@ public class ConvertPDFToOffice {
|
|||||||
description =
|
description =
|
||||||
"This endpoint converts a PDF file to an XML file. Input:PDF Output:XML"
|
"This endpoint converts a PDF file to an XML file. Input:PDF Output:XML"
|
||||||
+ " Type:SISO")
|
+ " Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToXML(@ModelAttribute PDFFile file)
|
public ResponseEntity<Resource> processPdfToXML(@ModelAttribute PDFFile file) throws Exception {
|
||||||
throws Exception {
|
|
||||||
MultipartFile inputFile = file.getFileInput();
|
MultipartFile inputFile = file.getFileInput();
|
||||||
|
|
||||||
PDFToFile pdfToFile = new PDFToFile(tempFileManager, runtimePathConfig);
|
PDFToFile pdfToFile = new PDFToFile(tempFileManager, runtimePathConfig);
|
||||||
|
|||||||
+4
-4
@@ -71,13 +71,13 @@ import org.apache.xmpbox.schema.PDFAIdentificationSchema;
|
|||||||
import org.apache.xmpbox.schema.XMPBasicSchema;
|
import org.apache.xmpbox.schema.XMPBasicSchema;
|
||||||
import org.apache.xmpbox.xml.DomXmpParser;
|
import org.apache.xmpbox.xml.DomXmpParser;
|
||||||
import org.apache.xmpbox.xml.XmpSerializer;
|
import org.apache.xmpbox.xml.XmpSerializer;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -577,7 +577,7 @@ public class ConvertPDFToPDFA {
|
|||||||
summary = "Convert a PDF to a PDF/A or PDF/X",
|
summary = "Convert a PDF to a PDF/A or PDF/X",
|
||||||
description =
|
description =
|
||||||
"This endpoint converts a PDF file to a PDF/A or PDF/X file using Ghostscript (preferred) or PDFBox/LibreOffice (fallback). PDF/A is a format designed for long-term archiving, while PDF/X is optimized for print production. Input:PDF Output:PDF Type:SISO")
|
"This endpoint converts a PDF file to a PDF/A or PDF/X file using Ghostscript (preferred) or PDFBox/LibreOffice (fallback). PDF/A is a format designed for long-term archiving, while PDF/X is optimized for print production. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> pdfToPdfA(@ModelAttribute PdfToPdfARequest request)
|
public ResponseEntity<Resource> pdfToPdfA(@ModelAttribute PdfToPdfARequest request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
String outputFormat = request.getOutputFormat();
|
String outputFormat = request.getOutputFormat();
|
||||||
@@ -613,7 +613,7 @@ public class ConvertPDFToPDFA {
|
|||||||
return missing;
|
return missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> handlePdfXConversion(
|
private ResponseEntity<Resource> handlePdfXConversion(
|
||||||
MultipartFile inputFile, String outputFormat) throws Exception {
|
MultipartFile inputFile, String outputFormat) throws Exception {
|
||||||
PdfXProfile profile = PdfXProfile.fromRequest(outputFormat);
|
PdfXProfile profile = PdfXProfile.fromRequest(outputFormat);
|
||||||
|
|
||||||
@@ -1806,7 +1806,7 @@ public class ConvertPDFToPDFA {
|
|||||||
return Files.readAllBytes(outputPdf);
|
return Files.readAllBytes(outputPdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> handlePdfAConversion(
|
private ResponseEntity<Resource> handlePdfAConversion(
|
||||||
MultipartFile inputFile, String outputFormat, boolean strict) throws Exception {
|
MultipartFile inputFile, String outputFormat, boolean strict) throws Exception {
|
||||||
PdfaProfile profile = PdfaProfile.fromRequest(outputFormat);
|
PdfaProfile profile = PdfaProfile.fromRequest(outputFormat);
|
||||||
|
|
||||||
|
|||||||
+77
-51
@@ -1,12 +1,16 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -15,7 +19,6 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -56,7 +59,7 @@ public class ConvertPdfJsonController {
|
|||||||
summary = "Convert PDF to Text Editor Format",
|
summary = "Convert PDF to Text Editor Format",
|
||||||
description =
|
description =
|
||||||
"Extracts PDF text, fonts, and metadata into an editable JSON structure for the text editor tool. Input:PDF Output:JSON Type:SISO")
|
"Extracts PDF text, fonts, and metadata into an editable JSON structure for the text editor tool. Input:PDF Output:JSON Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertPdfToJson(
|
public ResponseEntity<Resource> convertPdfToJson(
|
||||||
@ModelAttribute PDFFile request,
|
@ModelAttribute PDFFile request,
|
||||||
@RequestParam(value = "lightweight", defaultValue = "false") boolean lightweight)
|
@RequestParam(value = "lightweight", defaultValue = "false") boolean lightweight)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -65,10 +68,6 @@ public class ConvertPdfJsonController {
|
|||||||
throw ExceptionUtils.createNullArgumentException("fileInput");
|
throw ExceptionUtils.createNullArgumentException("fileInput");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor PdfJsonConversionService to write directly to an OutputStream
|
|
||||||
// instead of returning byte[], avoiding the intermediate heap allocation + temp file write
|
|
||||||
byte[] jsonBytes = pdfJsonConversionService.convertPdfToJson(inputFile, lightweight);
|
|
||||||
logJsonResponse("pdf/text-editor", jsonBytes);
|
|
||||||
String originalName = inputFile.getOriginalFilename();
|
String originalName = inputFile.getOriginalFilename();
|
||||||
String baseName =
|
String baseName =
|
||||||
(originalName != null && !originalName.isBlank())
|
(originalName != null && !originalName.isBlank())
|
||||||
@@ -78,13 +77,19 @@ public class ConvertPdfJsonController {
|
|||||||
: "document";
|
: "document";
|
||||||
String docName = baseName + ".json";
|
String docName = baseName + ".json";
|
||||||
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
||||||
try {
|
try (OutputStream os = Files.newOutputStream(tempOut.getPath())) {
|
||||||
Files.write(tempOut.getPath(), jsonBytes);
|
pdfJsonConversionService.convertPdfToJson(inputFile, lightweight, os);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tempOut.close();
|
tempOut.close();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
logJsonResponse("pdf/text-editor", tempOut.getPath());
|
||||||
return WebResponseUtils.fileToWebResponse(tempOut, docName, MediaType.APPLICATION_JSON);
|
return WebResponseUtils.fileToWebResponse(tempOut, docName, MediaType.APPLICATION_JSON);
|
||||||
|
} catch (Exception e) {
|
||||||
|
tempOut.close();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/text-editor/pdf")
|
@AutoJobPostMapping(consumes = "multipart/form-data", value = "/text-editor/pdf")
|
||||||
@@ -93,14 +98,13 @@ public class ConvertPdfJsonController {
|
|||||||
summary = "Convert Text Editor Format to PDF",
|
summary = "Convert Text Editor Format to PDF",
|
||||||
description =
|
description =
|
||||||
"Rebuilds a PDF from the editable JSON structure generated by the text editor tool. Input:JSON Output:PDF Type:SISO")
|
"Rebuilds a PDF from the editable JSON structure generated by the text editor tool. Input:JSON Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertJsonToPdf(
|
public ResponseEntity<Resource> convertJsonToPdf(@ModelAttribute GeneralFile request)
|
||||||
@ModelAttribute GeneralFile request) throws Exception {
|
throws Exception {
|
||||||
MultipartFile jsonFile = request.getFileInput();
|
MultipartFile jsonFile = request.getFileInput();
|
||||||
if (jsonFile == null) {
|
if (jsonFile == null) {
|
||||||
throw ExceptionUtils.createNullArgumentException("fileInput");
|
throw ExceptionUtils.createNullArgumentException("fileInput");
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] pdfBytes = pdfJsonConversionService.convertJsonToPdf(jsonFile);
|
|
||||||
String originalName = jsonFile.getOriginalFilename();
|
String originalName = jsonFile.getOriginalFilename();
|
||||||
String baseName =
|
String baseName =
|
||||||
(originalName != null && !originalName.isBlank())
|
(originalName != null && !originalName.isBlank())
|
||||||
@@ -110,8 +114,8 @@ public class ConvertPdfJsonController {
|
|||||||
: "document";
|
: "document";
|
||||||
String docName = baseName.endsWith(".pdf") ? baseName : baseName + ".pdf";
|
String docName = baseName.endsWith(".pdf") ? baseName : baseName + ".pdf";
|
||||||
TempFile tempOut = tempFileManager.createManagedTempFile(".pdf");
|
TempFile tempOut = tempFileManager.createManagedTempFile(".pdf");
|
||||||
try {
|
try (OutputStream os = Files.newOutputStream(tempOut.getPath())) {
|
||||||
Files.write(tempOut.getPath(), pdfBytes);
|
pdfJsonConversionService.convertJsonToPdf(jsonFile, os);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tempOut.close();
|
tempOut.close();
|
||||||
throw e;
|
throw e;
|
||||||
@@ -126,7 +130,7 @@ public class ConvertPdfJsonController {
|
|||||||
"Extracts document metadata, fonts, and page dimensions for the text editor tool. Caches the document for"
|
"Extracts document metadata, fonts, and page dimensions for the text editor tool. Caches the document for"
|
||||||
+ " subsequent page requests. Returns a server-generated jobId scoped to the"
|
+ " subsequent page requests. Returns a server-generated jobId scoped to the"
|
||||||
+ " authenticated user. Input:PDF Output:JSON Type:SISO")
|
+ " authenticated user. Input:PDF Output:JSON Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> extractPdfMetadata(@ModelAttribute PDFFile request)
|
public ResponseEntity<Resource> extractPdfMetadata(@ModelAttribute PDFFile request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
if (inputFile == null) {
|
if (inputFile == null) {
|
||||||
@@ -139,30 +143,24 @@ public class ConvertPdfJsonController {
|
|||||||
|
|
||||||
log.debug("Extracting metadata for PDF, assigned jobId: {}", scopedJobKey);
|
log.debug("Extracting metadata for PDF, assigned jobId: {}", scopedJobKey);
|
||||||
|
|
||||||
byte[] jsonBytes =
|
|
||||||
pdfJsonConversionService.extractDocumentMetadata(inputFile, scopedJobKey);
|
|
||||||
logJsonResponse("pdf/text-editor/metadata", jsonBytes);
|
|
||||||
|
|
||||||
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
||||||
try {
|
try (OutputStream os = Files.newOutputStream(tempOut.getPath())) {
|
||||||
Files.write(tempOut.getPath(), jsonBytes);
|
pdfJsonConversionService.extractDocumentMetadata(inputFile, scopedJobKey, os);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tempOut.close();
|
tempOut.close();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
logJsonResponse("pdf/text-editor/metadata", tempOut.getPath());
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.header("X-Job-Id", scopedJobKey)
|
.header("X-Job-Id", scopedJobKey)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.contentLength(java.nio.file.Files.size(tempOut.getPath()))
|
.contentLength(Files.size(tempOut.getPath()))
|
||||||
.body(
|
.body(new WebResponseUtils.ManagedTempFileResource(tempOut));
|
||||||
os -> {
|
} catch (IOException | RuntimeException e) {
|
||||||
try (os) {
|
|
||||||
Files.copy(tempOut.getPath(), os);
|
|
||||||
os.flush();
|
|
||||||
} finally {
|
|
||||||
tempOut.close();
|
tempOut.close();
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(
|
@AutoJobPostMapping(
|
||||||
@@ -175,7 +173,7 @@ public class ConvertPdfJsonController {
|
|||||||
"Applies edits for the specified pages of a cached PDF and returns an updated PDF."
|
"Applies edits for the specified pages of a cached PDF and returns an updated PDF."
|
||||||
+ " Requires the PDF to have been previously cached via the text editor metadata endpoint."
|
+ " Requires the PDF to have been previously cached via the text editor metadata endpoint."
|
||||||
+ " The jobId must be obtained from the metadata extraction endpoint.")
|
+ " The jobId must be obtained from the metadata extraction endpoint.")
|
||||||
public ResponseEntity<StreamingResponseBody> exportPartialPdf(
|
public ResponseEntity<Resource> exportPartialPdf(
|
||||||
@PathVariable String jobId,
|
@PathVariable String jobId,
|
||||||
@RequestBody PdfJsonDocument document,
|
@RequestBody PdfJsonDocument document,
|
||||||
@RequestParam(value = "filename", required = false) String filename)
|
@RequestParam(value = "filename", required = false) String filename)
|
||||||
@@ -215,22 +213,26 @@ public class ConvertPdfJsonController {
|
|||||||
"Retrieves a single page's content from a previously cached PDF document for the text editor tool."
|
"Retrieves a single page's content from a previously cached PDF document for the text editor tool."
|
||||||
+ " Requires prior call to /pdf/text-editor/metadata. The jobId must belong to the"
|
+ " Requires prior call to /pdf/text-editor/metadata. The jobId must belong to the"
|
||||||
+ " authenticated user. Output:JSON")
|
+ " authenticated user. Output:JSON")
|
||||||
public ResponseEntity<StreamingResponseBody> extractSinglePage(
|
public ResponseEntity<Resource> extractSinglePage(
|
||||||
@PathVariable String jobId, @PathVariable int pageNumber) throws Exception {
|
@PathVariable String jobId, @PathVariable int pageNumber) throws Exception {
|
||||||
|
|
||||||
validateJobAccess(jobId);
|
validateJobAccess(jobId);
|
||||||
|
|
||||||
byte[] jsonBytes = pdfJsonConversionService.extractSinglePage(jobId, pageNumber);
|
|
||||||
logJsonResponse("pdf/text-editor/page", jsonBytes);
|
|
||||||
String docName = "page_" + pageNumber + ".json";
|
String docName = "page_" + pageNumber + ".json";
|
||||||
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
||||||
try {
|
try (OutputStream os = Files.newOutputStream(tempOut.getPath())) {
|
||||||
Files.write(tempOut.getPath(), jsonBytes);
|
pdfJsonConversionService.extractSinglePage(jobId, pageNumber, os);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tempOut.close();
|
tempOut.close();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
logJsonResponse("pdf/text-editor/page", tempOut.getPath());
|
||||||
return WebResponseUtils.fileToWebResponse(tempOut, docName, MediaType.APPLICATION_JSON);
|
return WebResponseUtils.fileToWebResponse(tempOut, docName, MediaType.APPLICATION_JSON);
|
||||||
|
} catch (Exception e) {
|
||||||
|
tempOut.close();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/pdf/text-editor/fonts/{jobId}/{pageNumber}")
|
@GetMapping(value = "/pdf/text-editor/fonts/{jobId}/{pageNumber}")
|
||||||
@@ -240,22 +242,26 @@ public class ConvertPdfJsonController {
|
|||||||
"Retrieves the font payloads used by a single page from a previously cached PDF document."
|
"Retrieves the font payloads used by a single page from a previously cached PDF document."
|
||||||
+ " Requires prior call to /pdf/text-editor/metadata. The jobId must belong to the"
|
+ " Requires prior call to /pdf/text-editor/metadata. The jobId must belong to the"
|
||||||
+ " authenticated user. Output:JSON")
|
+ " authenticated user. Output:JSON")
|
||||||
public ResponseEntity<StreamingResponseBody> extractPageFonts(
|
public ResponseEntity<Resource> extractPageFonts(
|
||||||
@PathVariable String jobId, @PathVariable int pageNumber) throws Exception {
|
@PathVariable String jobId, @PathVariable int pageNumber) throws Exception {
|
||||||
|
|
||||||
validateJobAccess(jobId);
|
validateJobAccess(jobId);
|
||||||
|
|
||||||
byte[] jsonBytes = pdfJsonConversionService.extractPageFonts(jobId, pageNumber);
|
|
||||||
logJsonResponse("pdf/text-editor/fonts/page", jsonBytes);
|
|
||||||
String docName = "page_fonts_" + pageNumber + ".json";
|
String docName = "page_fonts_" + pageNumber + ".json";
|
||||||
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
TempFile tempOut = tempFileManager.createManagedTempFile(".json");
|
||||||
try {
|
try (OutputStream os = Files.newOutputStream(tempOut.getPath())) {
|
||||||
Files.write(tempOut.getPath(), jsonBytes);
|
pdfJsonConversionService.extractPageFonts(jobId, pageNumber, os);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
tempOut.close();
|
tempOut.close();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
logJsonResponse("pdf/text-editor/fonts/page", tempOut.getPath());
|
||||||
return WebResponseUtils.fileToWebResponse(tempOut, docName, MediaType.APPLICATION_JSON);
|
return WebResponseUtils.fileToWebResponse(tempOut, docName, MediaType.APPLICATION_JSON);
|
||||||
|
} catch (Exception e) {
|
||||||
|
tempOut.close();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AutoJobPostMapping(
|
@AutoJobPostMapping(
|
||||||
@@ -282,13 +288,34 @@ public class ConvertPdfJsonController {
|
|||||||
return baseJobId;
|
return baseJobId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logJsonResponse(String label, byte[] jsonBytes) {
|
private void logJsonResponse(String label, Path jsonPath) {
|
||||||
if (jsonBytes == null) {
|
if (jsonPath == null) {
|
||||||
log.warn("Returning {} JSON response: null bytes", label);
|
log.warn("Returning {} JSON response: null path", label);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
boolean debugEnabled = log.isDebugEnabled();
|
||||||
|
boolean dumpEnabled = isPdfJsonDebugDumpEnabled();
|
||||||
|
boolean repeatScanEnabled = isPdfJsonRepeatScanEnabled();
|
||||||
|
|
||||||
|
// Reading the full file back from disk is only worth it for these diagnostic paths.
|
||||||
|
// The happy path (no debug flags) returns here immediately — no extra IO.
|
||||||
|
if (!debugEnabled && !dumpEnabled && !repeatScanEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] jsonBytes;
|
||||||
|
try {
|
||||||
|
jsonBytes = Files.readAllBytes(jsonPath);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
log.warn(
|
||||||
|
"Failed to read PDF JSON ({}) for diagnostic logging: {}",
|
||||||
|
label,
|
||||||
|
ex.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debugEnabled) {
|
||||||
int length = jsonBytes.length;
|
int length = jsonBytes.length;
|
||||||
boolean endsWithJson =
|
boolean endsWithJson =
|
||||||
length > 0 && (jsonBytes[length - 1] == '}' || jsonBytes[length - 1] == ']');
|
length > 0 && (jsonBytes[length - 1] == '}' || jsonBytes[length - 1] == ']');
|
||||||
@@ -309,24 +336,23 @@ public class ConvertPdfJsonController {
|
|||||||
tail);
|
tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPdfJsonDebugDumpEnabled()) {
|
if (dumpEnabled) {
|
||||||
try {
|
try {
|
||||||
String tmpDir = System.getProperty("java.io.tmpdir");
|
String tmpDir = System.getProperty("java.io.tmpdir");
|
||||||
String customDir = System.getenv("SPDF_PDFJSON_DUMP_DIR");
|
String customDir = System.getenv("SPDF_PDFJSON_DUMP_DIR");
|
||||||
java.nio.file.Path dumpDir =
|
Path dumpDir =
|
||||||
customDir != null && !customDir.isBlank()
|
customDir != null && !customDir.isBlank()
|
||||||
? java.nio.file.Path.of(customDir)
|
? Path.of(customDir)
|
||||||
: java.nio.file.Path.of(tmpDir);
|
: Path.of(tmpDir);
|
||||||
java.nio.file.Path dumpPath =
|
Path dumpPath = Files.createTempFile(dumpDir, "pdfjson_", ".json");
|
||||||
java.nio.file.Files.createTempFile(dumpDir, "pdfjson_", ".json");
|
Files.copy(jsonPath, dumpPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||||||
java.nio.file.Files.write(dumpPath, jsonBytes);
|
|
||||||
log.debug("PDF JSON debug dump ({}): {}", label, dumpPath);
|
log.debug("PDF JSON debug dump ({}): {}", label, dumpPath);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.warn("Failed to write PDF JSON debug dump ({}): {}", label, ex.getMessage());
|
log.warn("Failed to write PDF JSON debug dump ({}): {}", label, ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPdfJsonRepeatScanEnabled()) {
|
if (repeatScanEnabled) {
|
||||||
logRepeatedJsonStrings(label, jsonBytes);
|
logRepeatedJsonStrings(label, jsonBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-16
@@ -9,12 +9,13 @@ import java.util.Locale;
|
|||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -54,8 +55,7 @@ public class ConvertSvgToPDF {
|
|||||||
+ "SVG dimensions (width/height) determine the PDF page size; defaults to A4 if not specified. "
|
+ "SVG dimensions (width/height) determine the PDF page size; defaults to A4 if not specified. "
|
||||||
+ "SVG content is sanitized to prevent XSS attacks. "
|
+ "SVG content is sanitized to prevent XSS attacks. "
|
||||||
+ "Input: SVG file(s), Output: PDF file(s) or ZIP. Type: MIMO")
|
+ "Input: SVG file(s), Output: PDF file(s) or ZIP. Type: MIMO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertSvgToPdf(
|
public ResponseEntity<Resource> convertSvgToPdf(@ModelAttribute SvgToPdfRequest request) {
|
||||||
@ModelAttribute SvgToPdfRequest request) {
|
|
||||||
|
|
||||||
MultipartFile[] inputFiles = request.getFileInput();
|
MultipartFile[] inputFiles = request.getFileInput();
|
||||||
boolean combineIntoSinglePdf = Boolean.TRUE.equals(request.getCombineIntoSinglePdf());
|
boolean combineIntoSinglePdf = Boolean.TRUE.equals(request.getCombineIntoSinglePdf());
|
||||||
@@ -95,10 +95,7 @@ public class ConvertSvgToPDF {
|
|||||||
filenames.add(Filenames.toSimpleFileName(originalFilename));
|
filenames.add(Filenames.toSimpleFileName(originalFilename));
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error(
|
log.error("SVG sanitization/reading failed for {}", originalFilename, e);
|
||||||
"SVG sanitization/reading failed for {}: {}",
|
|
||||||
originalFilename,
|
|
||||||
e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,17 +118,14 @@ public class ConvertSvgToPDF {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> errorResponse(HttpStatus status, String message) {
|
private ResponseEntity<Resource> errorResponse(HttpStatus status, String message) {
|
||||||
byte[] body = message.getBytes(StandardCharsets.UTF_8);
|
byte[] body = message.getBytes(StandardCharsets.UTF_8);
|
||||||
StreamingResponseBody streaming =
|
return ResponseEntity.status(status)
|
||||||
os -> {
|
.contentLength(body.length)
|
||||||
os.write(body);
|
.body(new ByteArrayResource(body));
|
||||||
os.flush();
|
|
||||||
};
|
|
||||||
return ResponseEntity.status(status).body(streaming);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> handleCombinedConversion(
|
private ResponseEntity<Resource> handleCombinedConversion(
|
||||||
List<byte[]> sanitizedSvgs, List<String> filenames) {
|
List<byte[]> sanitizedSvgs, List<String> filenames) {
|
||||||
try {
|
try {
|
||||||
log.info("Combining {} SVG files into single PDF", sanitizedSvgs.size());
|
log.info("Combining {} SVG files into single PDF", sanitizedSvgs.size());
|
||||||
@@ -169,7 +163,7 @@ public class ConvertSvgToPDF {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> handleSeparateConversion(
|
private ResponseEntity<Resource> handleSeparateConversion(
|
||||||
List<byte[]> sanitizedSvgs, List<String> filenames) {
|
List<byte[]> sanitizedSvgs, List<String> filenames) {
|
||||||
List<ConvertedPdf> convertedPdfs = new ArrayList<>();
|
List<ConvertedPdf> convertedPdfs = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -10,10 +10,10 @@ import java.util.Locale;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ public class PdfVectorExportController {
|
|||||||
description =
|
description =
|
||||||
"Converts PostScript vector inputs (PS, EPS, EPSF) to PDF using Ghostscript."
|
"Converts PostScript vector inputs (PS, EPS, EPSF) to PDF using Ghostscript."
|
||||||
+ " Input:PS/EPS Output:PDF Type:SISO")
|
+ " Input:PS/EPS Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertGhostscriptInputsToPdf(
|
public ResponseEntity<Resource> convertGhostscriptInputsToPdf(
|
||||||
@Valid @ModelAttribute PdfVectorExportRequest request) throws Exception {
|
@Valid @ModelAttribute PdfVectorExportRequest request) throws Exception {
|
||||||
|
|
||||||
String originalName =
|
String originalName =
|
||||||
@@ -98,7 +98,7 @@ public class PdfVectorExportController {
|
|||||||
description =
|
description =
|
||||||
"Converts PDF to Ghostscript vector formats (EPS, PS, PCL, or XPS)."
|
"Converts PDF to Ghostscript vector formats (EPS, PS, PCL, or XPS)."
|
||||||
+ " Input:PDF Output:VECTOR Type:SISO")
|
+ " Input:PDF Output:VECTOR Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> convertPdfToVector(
|
public ResponseEntity<Resource> convertPdfToVector(
|
||||||
@Valid @ModelAttribute PdfVectorExportRequest request) throws Exception {
|
@Valid @ModelAttribute PdfVectorExportRequest request) throws Exception {
|
||||||
|
|
||||||
String originalName =
|
String originalName =
|
||||||
|
|||||||
+5
-5
@@ -5,11 +5,11 @@ import java.io.IOException;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -56,8 +56,8 @@ public class FilterController {
|
|||||||
description = "PDF did not pass filter",
|
description = "PDF did not pass filter",
|
||||||
content = @Content())
|
content = @Content())
|
||||||
})
|
})
|
||||||
public ResponseEntity<StreamingResponseBody> containsText(
|
public ResponseEntity<Resource> containsText(@ModelAttribute ContainsTextRequest request)
|
||||||
@ModelAttribute ContainsTextRequest request) throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
String text = request.getText();
|
String text = request.getText();
|
||||||
String pageNumber = request.getPageNumbers();
|
String pageNumber = request.getPageNumbers();
|
||||||
@@ -89,8 +89,8 @@ public class FilterController {
|
|||||||
description = "PDF did not pass filter",
|
description = "PDF did not pass filter",
|
||||||
content = @Content())
|
content = @Content())
|
||||||
})
|
})
|
||||||
public ResponseEntity<StreamingResponseBody> containsImage(
|
public ResponseEntity<Resource> containsImage(@ModelAttribute PDFWithPageNums request)
|
||||||
@ModelAttribute PDFWithPageNums request) throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
String pageNumber = request.getPageNumbers();
|
String pageNumber = request.getPageNumbers();
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -10,6 +10,7 @@ import java.util.Map;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -18,7 +19,6 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.RequestPart;
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import com.opencsv.CSVWriter;
|
import com.opencsv.CSVWriter;
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public class FormFillController {
|
|||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
private final TempFileManager tempFileManager;
|
private final TempFileManager tempFileManager;
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> saveDocument(PDDocument document, String baseName)
|
private ResponseEntity<Resource> saveDocument(PDDocument document, String baseName)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return WebResponseUtils.pdfDocToWebResponse(document, baseName + ".pdf", tempFileManager);
|
return WebResponseUtils.pdfDocToWebResponse(document, baseName + ".pdf", tempFileManager);
|
||||||
}
|
}
|
||||||
@@ -262,7 +262,7 @@ public class FormFillController {
|
|||||||
summary = "Modify existing form fields",
|
summary = "Modify existing form fields",
|
||||||
description =
|
description =
|
||||||
"Updates existing fields in the provided PDF and returns the updated file")
|
"Updates existing fields in the provided PDF and returns the updated file")
|
||||||
public ResponseEntity<StreamingResponseBody> modifyFields(
|
public ResponseEntity<Resource> modifyFields(
|
||||||
@Parameter(
|
@Parameter(
|
||||||
description = "The input PDF file",
|
description = "The input PDF file",
|
||||||
required = true,
|
required = true,
|
||||||
@@ -293,7 +293,7 @@ public class FormFillController {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Delete form fields",
|
summary = "Delete form fields",
|
||||||
description = "Removes the specified fields from the PDF and returns the updated file")
|
description = "Removes the specified fields from the PDF and returns the updated file")
|
||||||
public ResponseEntity<StreamingResponseBody> deleteFields(
|
public ResponseEntity<Resource> deleteFields(
|
||||||
@Parameter(
|
@Parameter(
|
||||||
description = "The input PDF file",
|
description = "The input PDF file",
|
||||||
required = true,
|
required = true,
|
||||||
@@ -329,7 +329,7 @@ public class FormFillController {
|
|||||||
description =
|
description =
|
||||||
"Populates the supplied PDF form using values from the provided JSON payload"
|
"Populates the supplied PDF form using values from the provided JSON payload"
|
||||||
+ " and returns the filled PDF")
|
+ " and returns the filled PDF")
|
||||||
public ResponseEntity<StreamingResponseBody> fillForm(
|
public ResponseEntity<Resource> fillForm(
|
||||||
@Parameter(
|
@Parameter(
|
||||||
description = "The input PDF file",
|
description = "The input PDF file",
|
||||||
required = true,
|
required = true,
|
||||||
@@ -356,7 +356,7 @@ public class FormFillController {
|
|||||||
document -> FormUtils.applyFieldValues(document, values, flatten, true));
|
document -> FormUtils.applyFieldValues(document, values, flatten, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseEntity<StreamingResponseBody> processSingleFile(
|
private ResponseEntity<Resource> processSingleFile(
|
||||||
MultipartFile file, String suffix, DocumentProcessor processor) throws IOException {
|
MultipartFile file, String suffix, DocumentProcessor processor) throws IOException {
|
||||||
requirePdf(file);
|
requirePdf(file);
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -6,11 +6,11 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -54,8 +54,8 @@ public class AttachmentController {
|
|||||||
summary = "Add attachments to PDF",
|
summary = "Add attachments to PDF",
|
||||||
description =
|
description =
|
||||||
"This endpoint adds attachments to a PDF. Input:PDF, Output:PDF Type:MISO")
|
"This endpoint adds attachments to a PDF. Input:PDF, Output:PDF Type:MISO")
|
||||||
public ResponseEntity<StreamingResponseBody> addAttachments(
|
public ResponseEntity<Resource> addAttachments(@ModelAttribute AddAttachmentRequest request)
|
||||||
@ModelAttribute AddAttachmentRequest request) throws Exception {
|
throws Exception {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
List<MultipartFile> attachments = request.getAttachments();
|
List<MultipartFile> attachments = request.getAttachments();
|
||||||
boolean convertToPdfA3b = request.isConvertToPdfA3b();
|
boolean convertToPdfA3b = request.isConvertToPdfA3b();
|
||||||
@@ -143,7 +143,7 @@ public class AttachmentController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint extracts all embedded attachments from a PDF into a ZIP archive."
|
"This endpoint extracts all embedded attachments from a PDF into a ZIP archive."
|
||||||
+ " Input:PDF Output:ZIP Type:SISO")
|
+ " Input:PDF Output:ZIP Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> extractAttachments(
|
public ResponseEntity<Resource> extractAttachments(
|
||||||
@ModelAttribute ExtractAttachmentsRequest request) throws IOException {
|
@ModelAttribute ExtractAttachmentsRequest request) throws IOException {
|
||||||
try (PDDocument document = pdfDocumentFactory.load(request, true)) {
|
try (PDDocument document = pdfDocumentFactory.load(request, true)) {
|
||||||
Optional<byte[]> extracted = pdfAttachmentService.extractAttachments(document);
|
Optional<byte[]> extracted = pdfAttachmentService.extractAttachments(document);
|
||||||
@@ -195,7 +195,7 @@ public class AttachmentController {
|
|||||||
summary = "Rename attachment in PDF",
|
summary = "Rename attachment in PDF",
|
||||||
description =
|
description =
|
||||||
"This endpoint renames an embedded attachment in a PDF. Input:PDF Output:PDF Type:MISO")
|
"This endpoint renames an embedded attachment in a PDF. Input:PDF Output:PDF Type:MISO")
|
||||||
public ResponseEntity<StreamingResponseBody> renameAttachment(
|
public ResponseEntity<Resource> renameAttachment(
|
||||||
@ModelAttribute RenameAttachmentRequest request) throws Exception {
|
@ModelAttribute RenameAttachmentRequest request) throws Exception {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
String attachmentName = request.getAttachmentName();
|
String attachmentName = request.getAttachmentName();
|
||||||
@@ -230,7 +230,7 @@ public class AttachmentController {
|
|||||||
summary = "Delete attachment from PDF",
|
summary = "Delete attachment from PDF",
|
||||||
description =
|
description =
|
||||||
"This endpoint deletes an embedded attachment from a PDF. Input:PDF Output:PDF Type:MISO")
|
"This endpoint deletes an embedded attachment from a PDF. Input:PDF Output:PDF Type:MISO")
|
||||||
public ResponseEntity<StreamingResponseBody> deleteAttachment(
|
public ResponseEntity<Resource> deleteAttachment(
|
||||||
@ModelAttribute DeleteAttachmentRequest request) throws Exception {
|
@ModelAttribute DeleteAttachmentRequest request) throws Exception {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
String attachmentName = request.getAttachmentName();
|
String attachmentName = request.getAttachmentName();
|
||||||
|
|||||||
+3
-3
@@ -8,11 +8,11 @@ import java.util.List;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.text.PDFTextStripper;
|
import org.apache.pdfbox.text.PDFTextStripper;
|
||||||
import org.apache.pdfbox.text.TextPosition;
|
import org.apache.pdfbox.text.TextPosition;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -45,8 +45,8 @@ public class AutoRenameController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint accepts a PDF file and attempts to extract its title or header"
|
"This endpoint accepts a PDF file and attempts to extract its title or header"
|
||||||
+ " based on heuristics. Input:PDF Output:PDF Type:SISO")
|
+ " based on heuristics. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> extractHeader(
|
public ResponseEntity<Resource> extractHeader(@ModelAttribute ExtractHeaderRequest request)
|
||||||
@ModelAttribute ExtractHeaderRequest request) throws Exception {
|
throws Exception {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
boolean useFirstTextAsFallback = Boolean.TRUE.equals(request.getUseFirstTextAsFallback());
|
boolean useFirstTextAsFallback = Boolean.TRUE.equals(request.getUseFirstTextAsFallback());
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -18,11 +18,11 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import com.google.zxing.*;
|
import com.google.zxing.*;
|
||||||
import com.google.zxing.common.GlobalHistogramBinarizer;
|
import com.google.zxing.common.GlobalHistogramBinarizer;
|
||||||
@@ -276,8 +276,8 @@ public class AutoSplitPdfController {
|
|||||||
+ " splits the document at the QR code boundaries. The output is a zip"
|
+ " splits the document at the QR code boundaries. The output is a zip"
|
||||||
+ " file containing each separate PDF document. Input:PDF Output:ZIP-PDF"
|
+ " file containing each separate PDF document. Input:PDF Output:ZIP-PDF"
|
||||||
+ " Type:SISO")
|
+ " Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> autoSplitPdf(
|
public ResponseEntity<Resource> autoSplitPdf(@ModelAttribute AutoSplitPdfRequest request)
|
||||||
@ModelAttribute AutoSplitPdfRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
boolean duplexMode = Boolean.TRUE.equals(request.getDuplexMode());
|
boolean duplexMode = Boolean.TRUE.equals(request.getDuplexMode());
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -15,12 +15,12 @@ import org.apache.pdfbox.pdmodel.PDPage;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
import org.apache.pdfbox.text.PDFTextStripper;
|
import org.apache.pdfbox.text.PDFTextStripper;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -88,7 +88,7 @@ public class BlankPageController {
|
|||||||
"This endpoint removes blank pages from a given PDF file. Users can specify the"
|
"This endpoint removes blank pages from a given PDF file. Users can specify the"
|
||||||
+ " threshold and white percentage to tune the detection of blank pages."
|
+ " threshold and white percentage to tune the detection of blank pages."
|
||||||
+ " Input:PDF Output:PDF Type:SISO")
|
+ " Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> removeBlankPages(
|
public ResponseEntity<Resource> removeBlankPages(
|
||||||
@ModelAttribute RemoveBlankPagesRequest request)
|
@ModelAttribute RemoveBlankPagesRequest request)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
|
|||||||
+3
-3
@@ -32,13 +32,13 @@ import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImage;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImage;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -928,8 +928,8 @@ public class CompressController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint accepts a PDF file and optimizes it based on the provided"
|
"This endpoint accepts a PDF file and optimizes it based on the provided"
|
||||||
+ " parameters. Input:PDF Output:PDF Type:SISO")
|
+ " parameters. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> optimizePdf(
|
public ResponseEntity<Resource> optimizePdf(@ModelAttribute OptimizePdfRequest request)
|
||||||
@ModelAttribute OptimizePdfRequest request) throws Exception {
|
throws Exception {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
|
|
||||||
// Validate input file
|
// Validate input file
|
||||||
|
|||||||
+2
-2
@@ -9,11 +9,11 @@ import org.apache.pdfbox.cos.*;
|
|||||||
import org.apache.pdfbox.io.IOUtils;
|
import org.apache.pdfbox.io.IOUtils;
|
||||||
import org.apache.pdfbox.pdfwriter.compress.CompressParameters;
|
import org.apache.pdfbox.pdfwriter.compress.CompressParameters;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ public class DecompressPdfController {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Decompress PDF streams",
|
summary = "Decompress PDF streams",
|
||||||
description = "Fully decompresses all PDF streams including text content")
|
description = "Fully decompresses all PDF streams including text content")
|
||||||
public ResponseEntity<StreamingResponseBody> decompressPdf(@ModelAttribute PDFFile request)
|
public ResponseEntity<Resource> decompressPdf(@ModelAttribute PDFFile request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|||||||
+4
-4
@@ -17,11 +17,11 @@ import javax.imageio.ImageIO;
|
|||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public class ExtractImageScansController {
|
|||||||
+ " parameters. Users can specify angle threshold, tolerance, minimum area,"
|
+ " parameters. Users can specify angle threshold, tolerance, minimum area,"
|
||||||
+ " minimum contour area, and border size. Input:PDF Output:IMAGE/ZIP"
|
+ " minimum contour area, and border size. Input:PDF Output:IMAGE/ZIP"
|
||||||
+ " Type:SIMO")
|
+ " Type:SIMO")
|
||||||
public ResponseEntity<StreamingResponseBody> extractImageScans(
|
public ResponseEntity<Resource> extractImageScans(
|
||||||
@ModelAttribute ExtractImageScansRequest request)
|
@ModelAttribute ExtractImageScansRequest request)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
@@ -198,7 +198,7 @@ public class ExtractImageScansController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
WebResponseUtils.zipFileToWebResponse(finalOutput, outputZipFilename);
|
WebResponseUtils.zipFileToWebResponse(finalOutput, outputZipFilename);
|
||||||
finalOutputOwnershipTransferred = true;
|
finalOutputOwnershipTransferred = true;
|
||||||
return response;
|
return response;
|
||||||
@@ -215,7 +215,7 @@ public class ExtractImageScansController {
|
|||||||
out.write(imageBytes);
|
out.write(imageBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
WebResponseUtils.fileToWebResponse(
|
WebResponseUtils.fileToWebResponse(
|
||||||
finalOutput,
|
finalOutput,
|
||||||
GeneralUtils.generateFilename(fileName, ".png"),
|
GeneralUtils.generateFilename(fileName, ".png"),
|
||||||
|
|||||||
+3
-3
@@ -19,11 +19,11 @@ import org.apache.pdfbox.cos.COSName;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -57,8 +57,8 @@ public class ExtractImagesController {
|
|||||||
"This endpoint extracts images from a given PDF file and returns them in a zip"
|
"This endpoint extracts images from a given PDF file and returns them in a zip"
|
||||||
+ " file. Users can specify the output image format. Input:PDF"
|
+ " file. Users can specify the output image format. Input:PDF"
|
||||||
+ " Output:IMAGE/ZIP Type:SIMO")
|
+ " Output:IMAGE/ZIP Type:SIMO")
|
||||||
public ResponseEntity<StreamingResponseBody> extractImages(
|
public ResponseEntity<Resource> extractImages(@ModelAttribute PDFExtractImagesRequest request)
|
||||||
@ModelAttribute PDFExtractImagesRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
String imageFormat = request.getFormat();
|
String imageFormat = request.getFormat();
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -11,11 +11,11 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
import org.apache.pdfbox.rendering.ImageType;
|
import org.apache.pdfbox.rendering.ImageType;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -49,7 +49,7 @@ public class FlattenController {
|
|||||||
description =
|
description =
|
||||||
"Flattening just PDF form fields or converting each page to images to make text"
|
"Flattening just PDF form fields or converting each page to images to make text"
|
||||||
+ " unselectable. Input:PDF, Output:PDF. Type:SISO")
|
+ " unselectable. Input:PDF, Output:PDF. Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> flatten(@ModelAttribute FlattenRequest request)
|
public ResponseEntity<Resource> flatten(@ModelAttribute FlattenRequest request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -8,12 +8,12 @@ import java.util.Map.Entry;
|
|||||||
import org.apache.pdfbox.cos.COSName;
|
import org.apache.pdfbox.cos.COSName;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -64,7 +64,7 @@ public class MetadataController {
|
|||||||
"This endpoint allows you to update the metadata of a given PDF file. You can"
|
"This endpoint allows you to update the metadata of a given PDF file. You can"
|
||||||
+ " add, modify, or delete standard and custom metadata fields. Input:PDF"
|
+ " add, modify, or delete standard and custom metadata fields. Input:PDF"
|
||||||
+ " Output:PDF Type:SISO")
|
+ " Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> metadata(@ModelAttribute MetadataRequest request)
|
public ResponseEntity<Resource> metadata(@ModelAttribute MetadataRequest request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
// Extract PDF file from the request object
|
// Extract PDF file from the request object
|
||||||
|
|||||||
+4
-4
@@ -21,11 +21,11 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
import org.apache.pdfbox.text.PDFTextStripper;
|
import org.apache.pdfbox.text.PDFTextStripper;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -90,7 +90,7 @@ public class OCRController {
|
|||||||
+ " specify languages, sidecar, deskew, clean, cleanFinal, ocrType, ocrRenderType,"
|
+ " specify languages, sidecar, deskew, clean, cleanFinal, ocrType, ocrRenderType,"
|
||||||
+ " and removeImagesAfter options. Uses OCRmyPDF if available, falls back to"
|
+ " and removeImagesAfter options. Uses OCRmyPDF if available, falls back to"
|
||||||
+ " Tesseract. Input:PDF Output:PDF Type:SI-Conditional")
|
+ " Tesseract. Input:PDF Output:PDF Type:SI-Conditional")
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfWithOCR(
|
public ResponseEntity<Resource> processPdfWithOCR(
|
||||||
@ModelAttribute ProcessPdfWithOcrRequest request)
|
@ModelAttribute ProcessPdfWithOcrRequest request)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
@@ -194,13 +194,13 @@ public class OCRController {
|
|||||||
// The intermediate PDF temp file is no longer needed; only the zip is streamed.
|
// The intermediate PDF temp file is no longer needed; only the zip is streamed.
|
||||||
tempOutputFile.close();
|
tempOutputFile.close();
|
||||||
pdfOwnershipTransferred = true;
|
pdfOwnershipTransferred = true;
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
WebResponseUtils.fileToWebResponse(
|
WebResponseUtils.fileToWebResponse(
|
||||||
tempZipFile, outputZipFilename, MediaType.APPLICATION_OCTET_STREAM);
|
tempZipFile, outputZipFilename, MediaType.APPLICATION_OCTET_STREAM);
|
||||||
zipOwnershipTransferred = true;
|
zipOwnershipTransferred = true;
|
||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response =
|
||||||
WebResponseUtils.pdfFileToWebResponse(tempOutputFile, outputFilename);
|
WebResponseUtils.pdfFileToWebResponse(tempOutputFile, outputFilename);
|
||||||
pdfOwnershipTransferred = true;
|
pdfOwnershipTransferred = true;
|
||||||
return response;
|
return response;
|
||||||
|
|||||||
+2
-3
@@ -6,12 +6,12 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -45,8 +45,7 @@ public class OverlayImageController {
|
|||||||
+ "SVG files are rendered as vector graphics for crisp output at any resolution. "
|
+ "SVG files are rendered as vector graphics for crisp output at any resolution. "
|
||||||
+ "The image can be overlaid on every page of the PDF if specified. "
|
+ "The image can be overlaid on every page of the PDF if specified. "
|
||||||
+ "Input:PDF/IMAGE/SVG Output:PDF Type:SISO")
|
+ "Input:PDF/IMAGE/SVG Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> overlayImage(
|
public ResponseEntity<Resource> overlayImage(@ModelAttribute OverlayImageRequest request) {
|
||||||
@ModelAttribute OverlayImageRequest request) {
|
|
||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
MultipartFile imageFile = request.getImageFile();
|
MultipartFile imageFile = request.getImageFile();
|
||||||
float x = request.getX();
|
float x = request.getX();
|
||||||
|
|||||||
+3
-3
@@ -11,11 +11,11 @@ import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||||
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -46,8 +46,8 @@ public class PageNumbersController {
|
|||||||
description =
|
description =
|
||||||
"This operation takes an input PDF file and adds page numbers to it. Input:PDF"
|
"This operation takes an input PDF file and adds page numbers to it. Input:PDF"
|
||||||
+ " Output:PDF Type:SISO")
|
+ " Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> addPageNumbers(
|
public ResponseEntity<Resource> addPageNumbers(@ModelAttribute AddPageNumbersRequest request)
|
||||||
@ModelAttribute AddPageNumbersRequest request) throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
String customMargin = request.getCustomMargin();
|
String customMargin = request.getCustomMargin();
|
||||||
|
|||||||
+2
-2
@@ -12,11 +12,11 @@ import org.apache.pdfbox.pdmodel.PDResources;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
|
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ public class RemoveImagesController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint removes all embedded images from a PDF file and returns the"
|
"This endpoint removes all embedded images from a PDF file and returns the"
|
||||||
+ " modified document. Input:PDF Output:PDF Type:SISO")
|
+ " modified document. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> removeImages(@ModelAttribute PDFFile request)
|
public ResponseEntity<Resource> removeImages(@ModelAttribute PDFFile request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
|
|||||||
+2
-2
@@ -4,11 +4,11 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public class RepairController {
|
|||||||
"This endpoint repairs a given PDF file by running Ghostscript (primary), qpdf (fallback), or PDFBox (if no external tools available). The PDF is"
|
"This endpoint repairs a given PDF file by running Ghostscript (primary), qpdf (fallback), or PDFBox (if no external tools available). The PDF is"
|
||||||
+ " first saved to a temporary location, repaired, read back, and then"
|
+ " first saved to a temporary location, repaired, read back, and then"
|
||||||
+ " returned as a response. Input:PDF Output:PDF Type:SISO")
|
+ " returned as a response. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> repairPdf(@ModelAttribute PDFFile file)
|
public ResponseEntity<Resource> repairPdf(@ModelAttribute PDFFile file)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
MultipartFile inputFile = file.getFileInput();
|
MultipartFile inputFile = file.getFileInput();
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,10 +6,10 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public class ReplaceAndInvertColorController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint accepts a PDF file and provides options to invert all colors, replace"
|
"This endpoint accepts a PDF file and provides options to invert all colors, replace"
|
||||||
+ " text and background colors, or convert to CMYK color space for printing. Input:PDF Output:PDF Type:SISO")
|
+ " text and background colors, or convert to CMYK color space for printing. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> replaceAndInvertColor(
|
public ResponseEntity<Resource> replaceAndInvertColor(
|
||||||
@ModelAttribute ReplaceAndInvertColorRequest request) throws IOException {
|
@ModelAttribute ReplaceAndInvertColorRequest request) throws IOException {
|
||||||
|
|
||||||
InputStreamResource resource =
|
InputStreamResource resource =
|
||||||
|
|||||||
+2
-2
@@ -30,11 +30,11 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
|
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ public class ScannerEffectController {
|
|||||||
summary = "Apply scanner effect to PDF",
|
summary = "Apply scanner effect to PDF",
|
||||||
description =
|
description =
|
||||||
"Applies various effects to simulate a scanned document, including rotation, noise, and edge softening. Input:PDF Output:PDF Type:SISO")
|
"Applies various effects to simulate a scanned document, including rotation, noise, and edge softening. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> scannerEffect(
|
public ResponseEntity<Resource> scannerEffect(
|
||||||
@Valid @ModelAttribute ScannerEffectRequest request) throws IOException {
|
@Valid @ModelAttribute ScannerEffectRequest request) throws IOException {
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -7,11 +7,11 @@ import java.util.Map;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
|
import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
|
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -39,8 +39,7 @@ public class ShowJavascript {
|
|||||||
@Operation(
|
@Operation(
|
||||||
summary = "Grabs all JS from a PDF and returns a single JS file with all code",
|
summary = "Grabs all JS from a PDF and returns a single JS file with all code",
|
||||||
description = "desc. Input:PDF Output:JS Type:SISO")
|
description = "desc. Input:PDF Output:JS Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> extractHeader(@ModelAttribute PDFFile file)
|
public ResponseEntity<Resource> extractHeader(@ModelAttribute PDFFile file) throws Exception {
|
||||||
throws Exception {
|
|
||||||
MultipartFile inputFile = file.getFileInput();
|
MultipartFile inputFile = file.getFileInput();
|
||||||
StringBuilder script = new StringBuilder();
|
StringBuilder script = new StringBuilder();
|
||||||
boolean foundScript = false;
|
boolean foundScript = false;
|
||||||
|
|||||||
+2
-2
@@ -31,13 +31,13 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.bind.annotation.InitBinder;
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ public class StampController {
|
|||||||
"This endpoint adds a stamp to a given PDF file. Users can specify the stamp"
|
"This endpoint adds a stamp to a given PDF file. Users can specify the stamp"
|
||||||
+ " type (text or image), rotation, opacity, width spacer, and height"
|
+ " type (text or image), rotation, opacity, width spacer, and height"
|
||||||
+ " spacer. Input:PDF Output:PDF Type:SISO")
|
+ " spacer. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> addStamp(@ModelAttribute AddStampRequest request)
|
public ResponseEntity<Resource> addStamp(@ModelAttribute AddStampRequest request)
|
||||||
throws IOException, Exception {
|
throws IOException, Exception {
|
||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
String pdfFileName = pdfFile.getOriginalFilename();
|
String pdfFileName = pdfFile.getOriginalFilename();
|
||||||
|
|||||||
+2
-2
@@ -10,10 +10,10 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.common.PDStream;
|
import org.apache.pdfbox.pdmodel.common.PDStream;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -49,7 +49,7 @@ public class UnlockPDFFormsController {
|
|||||||
description =
|
description =
|
||||||
"Removing read-only property from form fields making them fillable"
|
"Removing read-only property from form fields making them fillable"
|
||||||
+ "Input:PDF, Output:PDF. Type:SISO")
|
+ "Input:PDF, Output:PDF. Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> unlockPDFForms(@ModelAttribute PDFFile file) {
|
public ResponseEntity<Resource> unlockPDFForms(@ModelAttribute PDFFile file) {
|
||||||
try (PDDocument document = pdfDocumentFactory.load(file)) {
|
try (PDDocument document = pdfDocumentFactory.load(file)) {
|
||||||
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
|
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -13,7 +13,6 @@ import org.springframework.http.MediaType;
|
|||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -58,8 +57,8 @@ public class PipelineController {
|
|||||||
"This endpoint processes multiple PDF files through a configurable pipeline of operations. "
|
"This endpoint processes multiple PDF files through a configurable pipeline of operations. "
|
||||||
+ "Users provide files and a JSON configuration defining the sequence of operations to perform. "
|
+ "Users provide files and a JSON configuration defining the sequence of operations to perform. "
|
||||||
+ "Input:PDF Output:PDF/ZIP Type:MIMO")
|
+ "Input:PDF Output:PDF/ZIP Type:MIMO")
|
||||||
public ResponseEntity<StreamingResponseBody> handleData(
|
public ResponseEntity<Resource> handleData(@ModelAttribute HandleDataRequest request)
|
||||||
@ModelAttribute HandleDataRequest request) throws DatabindException, JacksonException {
|
throws DatabindException, JacksonException {
|
||||||
MultipartFile[] files = request.getFileInput();
|
MultipartFile[] files = request.getFileInput();
|
||||||
String jsonString = request.getJson();
|
String jsonString = request.getJson();
|
||||||
if (files == null) {
|
if (files == null) {
|
||||||
|
|||||||
+3
-3
@@ -55,6 +55,7 @@ import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
|||||||
import org.bouncycastle.pkcs.PKCSException;
|
import org.bouncycastle.pkcs.PKCSException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
@@ -64,7 +65,6 @@ import org.springframework.web.bind.annotation.ModelAttribute;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.micrometer.common.util.StringUtils;
|
import io.micrometer.common.util.StringUtils;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -168,8 +168,8 @@ public class CertSignController {
|
|||||||
"This endpoint accepts a PDF file, a digital certificate and related"
|
"This endpoint accepts a PDF file, a digital certificate and related"
|
||||||
+ " information to sign the PDF. It then returns the digitally signed PDF"
|
+ " information to sign the PDF. It then returns the digitally signed PDF"
|
||||||
+ " file. Input:PDF Output:PDF Type:SISO")
|
+ " file. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> signPDFWithCert(
|
public ResponseEntity<Resource> signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request)
|
||||||
@ModelAttribute SignPDFWithCertRequest request) throws Exception {
|
throws Exception {
|
||||||
MultipartFile pdf = request.getFileInput();
|
MultipartFile pdf = request.getFileInput();
|
||||||
String certType = request.getCertType();
|
String certType = request.getCertType();
|
||||||
MultipartFile privateKeyFile = request.getPrivateKeyFile();
|
MultipartFile privateKeyFile = request.getPrivateKeyFile();
|
||||||
|
|||||||
+5
-5
@@ -5,11 +5,11 @@ import java.io.IOException;
|
|||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
|
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
|
||||||
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
|
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -40,8 +40,8 @@ public class PasswordController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint removes the password from a protected PDF file. Users need to"
|
"This endpoint removes the password from a protected PDF file. Users need to"
|
||||||
+ " provide the existing password. Input:PDF Output:PDF Type:SISO")
|
+ " provide the existing password. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> removePassword(
|
public ResponseEntity<Resource> removePassword(@ModelAttribute PDFPasswordRequest request)
|
||||||
@ModelAttribute PDFPasswordRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
String password = request.getPassword();
|
String password = request.getPassword();
|
||||||
|
|
||||||
@@ -70,8 +70,8 @@ public class PasswordController {
|
|||||||
"This endpoint adds password protection to a PDF file. Users can specify a set"
|
"This endpoint adds password protection to a PDF file. Users can specify a set"
|
||||||
+ " of permissions that should be applied to the file. Input:PDF"
|
+ " of permissions that should be applied to the file. Input:PDF"
|
||||||
+ " Output:PDF")
|
+ " Output:PDF")
|
||||||
public ResponseEntity<StreamingResponseBody> addPassword(
|
public ResponseEntity<Resource> addPassword(@ModelAttribute AddPasswordRequest request)
|
||||||
@ModelAttribute AddPasswordRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile fileInput = request.getFileInput();
|
MultipartFile fileInput = request.getFileInput();
|
||||||
String ownerPassword = request.getOwnerPassword();
|
String ownerPassword = request.getOwnerPassword();
|
||||||
String password = request.getPassword();
|
String password = request.getPassword();
|
||||||
|
|||||||
+4
-5
@@ -33,13 +33,13 @@ import org.apache.pdfbox.pdmodel.common.PDStream;
|
|||||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
|
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
|
||||||
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.bind.annotation.InitBinder;
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.github.pixee.security.Filenames;
|
import io.github.pixee.security.Filenames;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -108,8 +108,8 @@ public class RedactController {
|
|||||||
"This endpoint redacts content from a PDF file based on manually specified areas. "
|
"This endpoint redacts content from a PDF file based on manually specified areas. "
|
||||||
+ "Users can specify areas to redact and optionally convert the PDF to an image. "
|
+ "Users can specify areas to redact and optionally convert the PDF to an image. "
|
||||||
+ "Input:PDF Output:PDF Type:SISO")
|
+ "Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> redactPDF(
|
public ResponseEntity<Resource> redactPDF(@ModelAttribute ManualRedactPdfRequest request)
|
||||||
@ModelAttribute ManualRedactPdfRequest request) throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
MultipartFile file = request.getFileInput();
|
MultipartFile file = request.getFileInput();
|
||||||
List<RedactionArea> redactionAreas = request.getRedactions();
|
List<RedactionArea> redactionAreas = request.getRedactions();
|
||||||
@@ -501,8 +501,7 @@ public class RedactController {
|
|||||||
"This endpoint automatically redacts text from a PDF file based on specified patterns. "
|
"This endpoint automatically redacts text from a PDF file based on specified patterns. "
|
||||||
+ "Users can provide text patterns to redact, with options for regex and whole word matching. "
|
+ "Users can provide text patterns to redact, with options for regex and whole word matching. "
|
||||||
+ "Input:PDF Output:PDF Type:SISO")
|
+ "Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> redactPdf(
|
public ResponseEntity<Resource> redactPdf(@ModelAttribute RedactPdfRequest request) {
|
||||||
@ModelAttribute RedactPdfRequest request) {
|
|
||||||
String[] listOfText = request.getListOfText().split("\n");
|
String[] listOfText = request.getListOfText().split("\n");
|
||||||
boolean useRegex = Boolean.TRUE.equals(request.getUseRegex());
|
boolean useRegex = Boolean.TRUE.equals(request.getUseRegex());
|
||||||
boolean wholeWordSearchBool = Boolean.TRUE.equals(request.getWholeWordSearch());
|
boolean wholeWordSearchBool = Boolean.TRUE.equals(request.getWholeWordSearch());
|
||||||
|
|||||||
+2
-2
@@ -7,11 +7,11 @@ import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ public class RemoveCertSignController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint accepts a PDF file and returns the PDF file without the digital"
|
"This endpoint accepts a PDF file and returns the PDF file without the digital"
|
||||||
+ " signature. Input:PDF, Output:PDF Type:SISO")
|
+ " signature. Input:PDF, Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> removeCertSignPDF(@ModelAttribute PDFFile request)
|
public ResponseEntity<Resource> removeCertSignPDF(@ModelAttribute PDFFile request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile pdf = request.getFileInput();
|
MultipartFile pdf = request.getFileInput();
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -24,11 +24,11 @@ import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
|
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -59,8 +59,8 @@ public class SanitizeController {
|
|||||||
description =
|
description =
|
||||||
"This endpoint processes a PDF file and removes specific elements based on the"
|
"This endpoint processes a PDF file and removes specific elements based on the"
|
||||||
+ " provided options. Input:PDF Output:PDF Type:SISO")
|
+ " provided options. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> sanitizePDF(
|
public ResponseEntity<Resource> sanitizePDF(@ModelAttribute SanitizePdfRequest request)
|
||||||
@ModelAttribute SanitizePdfRequest request) throws IOException {
|
throws IOException {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
boolean removeJavaScript = Boolean.TRUE.equals(request.getRemoveJavaScript());
|
boolean removeJavaScript = Boolean.TRUE.equals(request.getRemoveJavaScript());
|
||||||
boolean removeEmbeddedFiles = Boolean.TRUE.equals(request.getRemoveEmbeddedFiles());
|
boolean removeEmbeddedFiles = Boolean.TRUE.equals(request.getRemoveEmbeddedFiles());
|
||||||
|
|||||||
+3
-3
@@ -28,11 +28,11 @@ import org.bouncycastle.tsp.TimeStampRequest;
|
|||||||
import org.bouncycastle.tsp.TimeStampRequestGenerator;
|
import org.bouncycastle.tsp.TimeStampRequestGenerator;
|
||||||
import org.bouncycastle.tsp.TimeStampResponse;
|
import org.bouncycastle.tsp.TimeStampResponse;
|
||||||
import org.bouncycastle.tsp.TimeStampToken;
|
import org.bouncycastle.tsp.TimeStampToken;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -87,8 +87,8 @@ public class TimestampController {
|
|||||||
+ " document timestamp into the PDF. Only a SHA-256 hash of the"
|
+ " document timestamp into the PDF. Only a SHA-256 hash of the"
|
||||||
+ " document is sent to the TSA — the PDF itself never leaves the"
|
+ " document is sent to the TSA — the PDF itself never leaves the"
|
||||||
+ " server. Input:PDF Output:PDF Type:SISO")
|
+ " server. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> timestampPdf(
|
public ResponseEntity<Resource> timestampPdf(@ModelAttribute TimestampPdfRequest request)
|
||||||
@ModelAttribute TimestampPdfRequest request) throws Exception {
|
throws Exception {
|
||||||
MultipartFile inputFile = request.getFileInput();
|
MultipartFile inputFile = request.getFileInput();
|
||||||
ApplicationProperties.Security.Timestamp tsConfig =
|
ApplicationProperties.Security.Timestamp tsConfig =
|
||||||
applicationProperties.getSecurity().getTimestamp();
|
applicationProperties.getSecurity().getTimestamp();
|
||||||
|
|||||||
+3
-3
@@ -24,13 +24,13 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
|||||||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||||
import org.apache.pdfbox.util.Matrix;
|
import org.apache.pdfbox.util.Matrix;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.WebDataBinder;
|
import org.springframework.web.bind.WebDataBinder;
|
||||||
import org.springframework.web.bind.annotation.InitBinder;
|
import org.springframework.web.bind.annotation.InitBinder;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -76,8 +76,8 @@ public class WatermarkController {
|
|||||||
"This endpoint adds a watermark to a given PDF file. Users can specify the"
|
"This endpoint adds a watermark to a given PDF file. Users can specify the"
|
||||||
+ " watermark type (text or image), rotation, opacity, width spacer, and"
|
+ " watermark type (text or image), rotation, opacity, width spacer, and"
|
||||||
+ " height spacer. Input:PDF Output:PDF Type:SISO")
|
+ " height spacer. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> addWatermark(
|
public ResponseEntity<Resource> addWatermark(@Valid @ModelAttribute AddWatermarkRequest request)
|
||||||
@Valid @ModelAttribute AddWatermarkRequest request) throws IOException, Exception {
|
throws IOException, Exception {
|
||||||
MultipartFile pdfFile = request.getFileInput();
|
MultipartFile pdfFile = request.getFileInput();
|
||||||
String pdfFileName = pdfFile.getOriginalFilename();
|
String pdfFileName = pdfFile.getOriginalFilename();
|
||||||
if (pdfFileName != null && (pdfFileName.contains("..") || pdfFileName.startsWith("/"))) {
|
if (pdfFileName != null && (pdfFileName.contains("..") || pdfFileName.startsWith("/"))) {
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
package stirling.software.SPDF.model.api.converters;
|
package stirling.software.SPDF.model.api.converters;
|
||||||
|
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ public class ConvertPDFToMarkdown {
|
|||||||
summary = "Convert PDF to Markdown",
|
summary = "Convert PDF to Markdown",
|
||||||
description =
|
description =
|
||||||
"This endpoint converts a PDF file to Markdown format. Input:PDF Output:Markdown Type:SISO")
|
"This endpoint converts a PDF file to Markdown format. Input:PDF Output:Markdown Type:SISO")
|
||||||
public ResponseEntity<StreamingResponseBody> processPdfToMarkdown(@ModelAttribute PDFFile file)
|
public ResponseEntity<Resource> processPdfToMarkdown(@ModelAttribute PDFFile file)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile inputFile = file.getFileInput();
|
MultipartFile inputFile = file.getFileInput();
|
||||||
PDFToFile pdfToFile = new PDFToFile(tempFileManager);
|
PDFToFile pdfToFile = new PDFToFile(tempFileManager);
|
||||||
|
|||||||
+32
-28
@@ -248,24 +248,28 @@ public class PdfJsonConversionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] convertPdfToJson(MultipartFile file) throws IOException {
|
public void convertPdfToJson(MultipartFile file, OutputStream out) throws IOException {
|
||||||
return convertPdfToJson(file, null, false);
|
convertPdfToJson(file, null, false, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] convertPdfToJson(MultipartFile file, boolean lightweight) throws IOException {
|
public void convertPdfToJson(MultipartFile file, boolean lightweight, OutputStream out)
|
||||||
return convertPdfToJson(file, null, lightweight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] convertPdfToJson(
|
|
||||||
MultipartFile file, Consumer<PdfJsonConversionProgress> progressCallback)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return convertPdfToJson(file, progressCallback, false);
|
convertPdfToJson(file, null, lightweight, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] convertPdfToJson(
|
public void convertPdfToJson(
|
||||||
MultipartFile file,
|
MultipartFile file,
|
||||||
Consumer<PdfJsonConversionProgress> progressCallback,
|
Consumer<PdfJsonConversionProgress> progressCallback,
|
||||||
boolean lightweight)
|
OutputStream out)
|
||||||
|
throws IOException {
|
||||||
|
convertPdfToJson(file, progressCallback, false, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void convertPdfToJson(
|
||||||
|
MultipartFile file,
|
||||||
|
Consumer<PdfJsonConversionProgress> progressCallback,
|
||||||
|
boolean lightweight,
|
||||||
|
OutputStream out)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw ExceptionUtils.createNullArgumentException("fileInput");
|
throw ExceptionUtils.createNullArgumentException("fileInput");
|
||||||
@@ -593,7 +597,9 @@ public class PdfJsonConversionService {
|
|||||||
pdfJson.getPages().size());
|
pdfJson.getPages().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] result = objectMapper.writeValueAsBytes(pdfJson);
|
// Stream JSON directly to the caller's OutputStream to avoid allocating the
|
||||||
|
// entire document on the heap before writing it out.
|
||||||
|
objectMapper.writeValue(out, pdfJson);
|
||||||
progress.accept(PdfJsonConversionProgress.complete());
|
progress.accept(PdfJsonConversionProgress.complete());
|
||||||
|
|
||||||
// Clear Type3 cache entries immediately for non-cached conversions
|
// Clear Type3 cache entries immediately for non-cached conversions
|
||||||
@@ -602,15 +608,13 @@ public class PdfJsonConversionService {
|
|||||||
if (!useLazyImages) {
|
if (!useLazyImages) {
|
||||||
clearType3CacheEntriesForJob(jobId);
|
clearType3CacheEntriesForJob(jobId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
closeQuietly(normalizedFile);
|
closeQuietly(normalizedFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] convertJsonToPdf(MultipartFile file) throws IOException {
|
public void convertJsonToPdf(MultipartFile file, OutputStream out) throws IOException {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw ExceptionUtils.createNullArgumentException("fileInput");
|
throw ExceptionUtils.createNullArgumentException("fileInput");
|
||||||
}
|
}
|
||||||
@@ -804,15 +808,11 @@ public class PdfJsonConversionService {
|
|||||||
log.info("JSON->PDF conversion complete: {} pages", pages.size());
|
log.info("JSON->PDF conversion complete: {} pages", pages.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
// Stream the PDF directly to the caller's OutputStream — PDFBox writes incrementally.
|
||||||
document.save(baos);
|
document.save(out);
|
||||||
byte[] result = baos.toByteArray();
|
|
||||||
|
|
||||||
// Clear Type3 cache entries for this conversion
|
// Clear Type3 cache entries for this conversion
|
||||||
clearType3CacheEntriesForJob(syntheticJobId);
|
clearType3CacheEntriesForJob(syntheticJobId);
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6075,7 +6075,8 @@ public class PdfJsonConversionService {
|
|||||||
* Extracts document metadata, fonts, and page dimensions without page content. Caches the PDF
|
* Extracts document metadata, fonts, and page dimensions without page content. Caches the PDF
|
||||||
* bytes for subsequent page requests.
|
* bytes for subsequent page requests.
|
||||||
*/
|
*/
|
||||||
public byte[] extractDocumentMetadata(MultipartFile file, String jobId) throws IOException {
|
public void extractDocumentMetadata(MultipartFile file, String jobId, OutputStream out)
|
||||||
|
throws IOException {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw ExceptionUtils.createNullArgumentException("fileInput");
|
throw ExceptionUtils.createNullArgumentException("fileInput");
|
||||||
}
|
}
|
||||||
@@ -6170,12 +6171,13 @@ public class PdfJsonConversionService {
|
|||||||
progress.accept(
|
progress.accept(
|
||||||
PdfJsonConversionProgress.of(100, "complete", "Metadata extraction complete"));
|
PdfJsonConversionProgress.of(100, "complete", "Metadata extraction complete"));
|
||||||
|
|
||||||
return objectMapper.writeValueAsBytes(docMetadata);
|
objectMapper.writeValue(out, docMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Extracts a single page from cached PDF bytes. Re-loads the PDF for each request. */
|
/** Extracts a single page from cached PDF bytes. Re-loads the PDF for each request. */
|
||||||
public byte[] extractSinglePage(String jobId, int pageNumber) throws IOException {
|
public void extractSinglePage(String jobId, int pageNumber, OutputStream out)
|
||||||
|
throws IOException {
|
||||||
CachedPdfDocument cached = getCachedDocument(jobId);
|
CachedPdfDocument cached = getCachedDocument(jobId);
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
throw new stirling.software.SPDF.exception.CacheUnavailableException(
|
throw new stirling.software.SPDF.exception.CacheUnavailableException(
|
||||||
@@ -6326,11 +6328,12 @@ public class PdfJsonConversionService {
|
|||||||
pageModel.getAnnotations().size(),
|
pageModel.getAnnotations().size(),
|
||||||
jobId);
|
jobId);
|
||||||
|
|
||||||
return objectMapper.writeValueAsBytes(pageModel);
|
objectMapper.writeValue(out, pageModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] extractPageFonts(String jobId, int pageNumber) throws IOException {
|
public void extractPageFonts(String jobId, int pageNumber, OutputStream out)
|
||||||
|
throws IOException {
|
||||||
CachedPdfDocument cached = getCachedDocument(jobId);
|
CachedPdfDocument cached = getCachedDocument(jobId);
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
throw new stirling.software.SPDF.exception.CacheUnavailableException(
|
throw new stirling.software.SPDF.exception.CacheUnavailableException(
|
||||||
@@ -6347,7 +6350,8 @@ public class PdfJsonConversionService {
|
|||||||
Map<PDFont, String> pageMap =
|
Map<PDFont, String> pageMap =
|
||||||
pageFontResources != null ? pageFontResources.get(pageNumber) : null;
|
pageFontResources != null ? pageFontResources.get(pageNumber) : null;
|
||||||
if (pageMap == null || pageMap.isEmpty()) {
|
if (pageMap == null || pageMap.isEmpty()) {
|
||||||
return objectMapper.writeValueAsBytes(Collections.emptyList());
|
objectMapper.writeValue(out, Collections.emptyList());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, PdfJsonFont> cachedFonts = cached.getFonts();
|
Map<String, PdfJsonFont> cachedFonts = cached.getFonts();
|
||||||
@@ -6375,7 +6379,7 @@ public class PdfJsonConversionService {
|
|||||||
pageFonts.sort(
|
pageFonts.sort(
|
||||||
Comparator.comparing(
|
Comparator.comparing(
|
||||||
PdfJsonFont::getUid, Comparator.nullsLast(Comparator.naturalOrder())));
|
PdfJsonFont::getUid, Comparator.nullsLast(Comparator.naturalOrder())));
|
||||||
return objectMapper.writeValueAsBytes(pageFonts);
|
objectMapper.writeValue(out, pageFonts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] exportUpdatedPages(String jobId, PdfJsonDocument updates) throws IOException {
|
public byte[] exportUpdatedPages(String jobId, PdfJsonDocument updates) throws IOException {
|
||||||
|
|||||||
+11
-8
@@ -1,6 +1,7 @@
|
|||||||
package stirling.software.SPDF.service.pdfjson;
|
package stirling.software.SPDF.service.pdfjson;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -81,14 +82,15 @@ public class PdfLazyLoadingService {
|
|||||||
* @param jobId The job ID for caching
|
* @param jobId The job ID for caching
|
||||||
* @param fonts Font map (will be populated)
|
* @param fonts Font map (will be populated)
|
||||||
* @param pageFontResources Page font resources map (will be populated)
|
* @param pageFontResources Page font resources map (will be populated)
|
||||||
* @return Serialized metadata JSON
|
* @param out The output stream to write the serialized metadata JSON to
|
||||||
* @throws IOException If extraction fails
|
* @throws IOException If extraction fails
|
||||||
*/
|
*/
|
||||||
public byte[] extractDocumentMetadata(
|
public void extractDocumentMetadata(
|
||||||
MultipartFile file,
|
MultipartFile file,
|
||||||
String jobId,
|
String jobId,
|
||||||
Map<String, PdfJsonFont> fonts,
|
Map<String, PdfJsonFont> fonts,
|
||||||
Map<Integer, Map<PDFont, String>> pageFontResources)
|
Map<Integer, Map<PDFont, String>> pageFontResources,
|
||||||
|
OutputStream out)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
throw ExceptionUtils.createNullArgumentException("fileInput");
|
throw ExceptionUtils.createNullArgumentException("fileInput");
|
||||||
@@ -160,7 +162,7 @@ public class PdfLazyLoadingService {
|
|||||||
progress.accept(
|
progress.accept(
|
||||||
PdfJsonConversionProgress.of(100, "complete", "Metadata extraction complete"));
|
PdfJsonConversionProgress.of(100, "complete", "Metadata extraction complete"));
|
||||||
|
|
||||||
return objectMapper.writeValueAsBytes(docMetadata);
|
objectMapper.writeValue(out, docMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,10 +176,10 @@ public class PdfLazyLoadingService {
|
|||||||
* @param filterImageXObjectsFromResources Function to filter image XObjects
|
* @param filterImageXObjectsFromResources Function to filter image XObjects
|
||||||
* @param extractText Function to extract text elements for the page
|
* @param extractText Function to extract text elements for the page
|
||||||
* @param extractAnnotations Function to extract annotations for the page
|
* @param extractAnnotations Function to extract annotations for the page
|
||||||
* @return Serialized page JSON
|
* @param out The output stream to write the serialized page JSON to
|
||||||
* @throws IOException If extraction fails
|
* @throws IOException If extraction fails
|
||||||
*/
|
*/
|
||||||
public byte[] extractSinglePage(
|
public void extractSinglePage(
|
||||||
String jobId,
|
String jobId,
|
||||||
int pageNumber,
|
int pageNumber,
|
||||||
java.util.function.Function<COSBase, PdfJsonCosValue> serializeCosValue,
|
java.util.function.Function<COSBase, PdfJsonCosValue> serializeCosValue,
|
||||||
@@ -186,7 +188,8 @@ public class PdfLazyLoadingService {
|
|||||||
java.util.function.BiFunction<PDDocument, Integer, List<PdfJsonTextElement>>
|
java.util.function.BiFunction<PDDocument, Integer, List<PdfJsonTextElement>>
|
||||||
extractText,
|
extractText,
|
||||||
java.util.function.BiFunction<PDDocument, Integer, List<PdfJsonAnnotation>>
|
java.util.function.BiFunction<PDDocument, Integer, List<PdfJsonAnnotation>>
|
||||||
extractAnnotations)
|
extractAnnotations,
|
||||||
|
OutputStream out)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
CachedPdfDocument cached = documentCache.get(jobId);
|
CachedPdfDocument cached = documentCache.get(jobId);
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
@@ -238,7 +241,7 @@ public class PdfLazyLoadingService {
|
|||||||
pageModel.getAnnotations().size(),
|
pageModel.getAnnotations().size(),
|
||||||
jobId);
|
jobId);
|
||||||
|
|
||||||
return objectMapper.writeValueAsBytes(pageModel);
|
objectMapper.writeValue(out, pageModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-24
@@ -20,11 +20,12 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.BookletImpositionRequest;
|
import stirling.software.SPDF.model.api.general.BookletImpositionRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -33,14 +34,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class BookletImpositionControllerTest {
|
class BookletImpositionControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +96,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(drainBody(response)).isNotEmpty();
|
assertThat(drainBody(response)).isNotEmpty();
|
||||||
@@ -126,8 +127,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(drainBody(response)).isNotEmpty();
|
assertThat(drainBody(response)).isNotEmpty();
|
||||||
@@ -144,8 +144,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -162,8 +161,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -180,8 +178,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -198,8 +195,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -216,8 +212,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -232,8 +227,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -261,8 +255,7 @@ class BookletImpositionControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(sourceDoc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.createBookletImposition(request);
|
||||||
controller.createBookletImposition(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-12
@@ -27,11 +27,12 @@ import org.junit.jupiter.params.provider.ValueSource;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
import stirling.software.SPDF.model.api.general.CropPdfForm;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -41,14 +42,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@DisplayName("CropController Tests")
|
@DisplayName("CropController Tests")
|
||||||
class CropControllerTest {
|
class CropControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +207,7 @@ class CropControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
||||||
.thenReturn(newDocument);
|
.thenReturn(newDocument);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = cropController.cropPdf(request);
|
ResponseEntity<Resource> response = cropController.cropPdf(request);
|
||||||
|
|
||||||
assertThat(response)
|
assertThat(response)
|
||||||
.isNotNull()
|
.isNotNull()
|
||||||
@@ -242,7 +244,7 @@ class CropControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
||||||
.thenReturn(newDocument);
|
.thenReturn(newDocument);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = cropController.cropPdf(request);
|
ResponseEntity<Resource> response = cropController.cropPdf(request);
|
||||||
|
|
||||||
assertThat(response).isNotNull();
|
assertThat(response).isNotNull();
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
@@ -282,7 +284,7 @@ class CropControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc))
|
||||||
.thenReturn(newDoc);
|
.thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = cropController.cropPdf(request);
|
ResponseEntity<Resource> response = cropController.cropPdf(request);
|
||||||
|
|
||||||
assertThat(response).isNotNull();
|
assertThat(response).isNotNull();
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
@@ -313,7 +315,7 @@ class CropControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(sourceDoc))
|
||||||
.thenReturn(newDoc);
|
.thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = cropController.cropPdf(request);
|
ResponseEntity<Resource> response = cropController.cropPdf(request);
|
||||||
|
|
||||||
assertThat(response).isNotNull();
|
assertThat(response).isNotNull();
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
@@ -676,7 +678,7 @@ class CropControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
||||||
.thenReturn(newDocument);
|
.thenReturn(newDocument);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = cropController.cropPdf(request);
|
ResponseEntity<Resource> response = cropController.cropPdf(request);
|
||||||
|
|
||||||
assertThat(response).isNotNull();
|
assertThat(response).isNotNull();
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
@@ -704,7 +706,7 @@ class CropControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDocument))
|
||||||
.thenReturn(newDocument);
|
.thenReturn(newDocument);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = cropController.cropPdf(request);
|
ResponseEntity<Resource> response = cropController.cropPdf(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
verify(mockDocument, times(1)).close();
|
verify(mockDocument, times(1)).close();
|
||||||
|
|||||||
+4
-4
@@ -25,10 +25,10 @@ import org.mockito.ArgumentMatchers;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.controller.api.EditTableOfContentsController.BookmarkItem;
|
import stirling.software.SPDF.controller.api.EditTableOfContentsController.BookmarkItem;
|
||||||
import stirling.software.SPDF.model.api.EditTableOfContentsRequest;
|
import stirling.software.SPDF.model.api.EditTableOfContentsRequest;
|
||||||
@@ -255,7 +255,7 @@ class EditTableOfContentsControllerTest {
|
|||||||
.save(any(File.class));
|
.save(any(File.class));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<StreamingResponseBody> result =
|
ResponseEntity<Resource> result =
|
||||||
editTableOfContentsController.editTableOfContents(request);
|
editTableOfContentsController.editTableOfContents(request);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
@@ -319,7 +319,7 @@ class EditTableOfContentsControllerTest {
|
|||||||
.save(any(File.class));
|
.save(any(File.class));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<StreamingResponseBody> result =
|
ResponseEntity<Resource> result =
|
||||||
editTableOfContentsController.editTableOfContents(request);
|
editTableOfContentsController.editTableOfContents(request);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
@@ -373,7 +373,7 @@ class EditTableOfContentsControllerTest {
|
|||||||
.save(any(File.class));
|
.save(any(File.class));
|
||||||
|
|
||||||
// When
|
// When
|
||||||
ResponseEntity<StreamingResponseBody> result =
|
ResponseEntity<Resource> result =
|
||||||
editTableOfContentsController.editTableOfContents(request);
|
editTableOfContentsController.editTableOfContents(request);
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
|||||||
+11
-9
@@ -18,11 +18,12 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
import stirling.software.SPDF.model.api.general.MergeMultiplePagesRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -31,14 +32,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class MultiPageLayoutControllerTest {
|
class MultiPageLayoutControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ class MultiPageLayoutControllerTest {
|
|||||||
req.setAddBorder(Boolean.FALSE);
|
req.setAddBorder(Boolean.FALSE);
|
||||||
req.setFileInput(fileWithExt);
|
req.setFileInput(fileWithExt);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> resp = controller.mergeMultiplePagesIntoOne(req);
|
ResponseEntity<Resource> resp = controller.mergeMultiplePagesIntoOne(req);
|
||||||
Assertions.assertEquals(HttpStatus.OK, resp.getStatusCode());
|
Assertions.assertEquals(HttpStatus.OK, resp.getStatusCode());
|
||||||
Assertions.assertEquals(MediaType.APPLICATION_PDF, resp.getHeaders().getContentType());
|
Assertions.assertEquals(MediaType.APPLICATION_PDF, resp.getHeaders().getContentType());
|
||||||
Assertions.assertNotNull(resp.getBody());
|
Assertions.assertNotNull(resp.getBody());
|
||||||
@@ -122,7 +124,7 @@ class MultiPageLayoutControllerTest {
|
|||||||
req.setAddBorder(Boolean.TRUE);
|
req.setAddBorder(Boolean.TRUE);
|
||||||
req.setFileInput(fileWithExt);
|
req.setFileInput(fileWithExt);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> resp = controller.mergeMultiplePagesIntoOne(req);
|
ResponseEntity<Resource> resp = controller.mergeMultiplePagesIntoOne(req);
|
||||||
Assertions.assertEquals(HttpStatus.OK, resp.getStatusCode());
|
Assertions.assertEquals(HttpStatus.OK, resp.getStatusCode());
|
||||||
Assertions.assertEquals(MediaType.APPLICATION_PDF, resp.getHeaders().getContentType());
|
Assertions.assertEquals(MediaType.APPLICATION_PDF, resp.getHeaders().getContentType());
|
||||||
Assertions.assertNotNull(resp.getBody());
|
Assertions.assertNotNull(resp.getBody());
|
||||||
@@ -145,7 +147,7 @@ class MultiPageLayoutControllerTest {
|
|||||||
req.setAddBorder(Boolean.TRUE);
|
req.setAddBorder(Boolean.TRUE);
|
||||||
req.setFileInput(fileNoExt);
|
req.setFileInput(fileNoExt);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> resp = controller.mergeMultiplePagesIntoOne(req);
|
ResponseEntity<Resource> resp = controller.mergeMultiplePagesIntoOne(req);
|
||||||
Assertions.assertEquals(
|
Assertions.assertEquals(
|
||||||
"name_multi_page_layout.pdf",
|
"name_multi_page_layout.pdf",
|
||||||
resp.getHeaders().getContentDisposition().getFilename());
|
resp.getHeaders().getContentDisposition().getFilename());
|
||||||
|
|||||||
+14
-12
@@ -25,12 +25,13 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
|
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -39,14 +40,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class PdfOverlayControllerTest {
|
class PdfOverlayControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ class PdfOverlayControllerTest {
|
|||||||
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
||||||
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayPdfs(request);
|
ResponseEntity<Resource> response = controller.overlayPdfs(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -141,7 +143,7 @@ class PdfOverlayControllerTest {
|
|||||||
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
||||||
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayPdfs(request);
|
ResponseEntity<Resource> response = controller.overlayPdfs(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -173,7 +175,7 @@ class PdfOverlayControllerTest {
|
|||||||
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
||||||
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayPdfs(request);
|
ResponseEntity<Resource> response = controller.overlayPdfs(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -204,7 +206,7 @@ class PdfOverlayControllerTest {
|
|||||||
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
||||||
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayPdfs(request);
|
ResponseEntity<Resource> response = controller.overlayPdfs(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -294,7 +296,7 @@ class PdfOverlayControllerTest {
|
|||||||
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
||||||
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayPdfs(request);
|
ResponseEntity<Resource> response = controller.overlayPdfs(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -327,7 +329,7 @@ class PdfOverlayControllerTest {
|
|||||||
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
when(pdfDocumentFactory.load(any(MultipartFile.class)))
|
||||||
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
.thenAnswer(inv -> Loader.loadPDF(((MultipartFile) inv.getArgument(0)).getBytes()));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayPdfs(request);
|
ResponseEntity<Resource> response = controller.overlayPdfs(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
|||||||
+12
-12
@@ -16,10 +16,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.SPDF.model.api.general.RearrangePagesRequest;
|
import stirling.software.SPDF.model.api.general.RearrangePagesRequest;
|
||||||
@@ -67,7 +67,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(mockDoc);
|
when(pdfDocumentFactory.load(file)).thenReturn(mockDoc);
|
||||||
when(mockDoc.getNumberOfPages()).thenReturn(5);
|
when(mockDoc.getNumberOfPages()).thenReturn(5);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.deletePages(request);
|
ResponseEntity<Resource> response = controller.deletePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -97,7 +97,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -127,7 +127,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
verify(mockNewDoc).addPage(page1);
|
verify(mockNewDoc).addPage(page1);
|
||||||
@@ -155,7 +155,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
verify(mockNewDoc).addPage(page0);
|
verify(mockNewDoc).addPage(page0);
|
||||||
@@ -181,7 +181,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -208,7 +208,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -232,7 +232,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -256,7 +256,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -284,7 +284,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -308,7 +308,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
// 2 pages * 3 duplicates = 6 addPage calls
|
// 2 pages * 3 duplicates = 6 addPage calls
|
||||||
@@ -333,7 +333,7 @@ class RearrangePagesPDFControllerTest {
|
|||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(mockDoc))
|
||||||
.thenReturn(mockNewDoc);
|
.thenReturn(mockNewDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.rearrangePages(request);
|
ResponseEntity<Resource> response = controller.rearrangePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
|
|||||||
+2
-2
@@ -20,10 +20,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
import stirling.software.SPDF.model.api.general.RotatePDFRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -75,7 +75,7 @@ public class RotationControllerTest {
|
|||||||
when(mockPage.getRotation()).thenReturn(0);
|
when(mockPage.getRotation()).thenReturn(0);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ResponseEntity<StreamingResponseBody> response = rotationController.rotatePDF(request);
|
ResponseEntity<Resource> response = rotationController.rotatePDF(request);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
verify(mockPage).setRotation(90);
|
verify(mockPage).setRotation(90);
|
||||||
|
|||||||
+16
-14
@@ -20,11 +20,12 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
import stirling.software.SPDF.model.api.general.ScalePagesRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -33,14 +34,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ScalePagesControllerTest {
|
class ScalePagesControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +103,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -123,7 +125,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -143,7 +145,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -163,7 +165,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -183,7 +185,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -220,7 +222,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -240,7 +242,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -281,7 +283,7 @@ class ScalePagesControllerTest {
|
|||||||
|
|
||||||
setupFactory();
|
setupFactory();
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.scalePages(request);
|
ResponseEntity<Resource> response = controller.scalePages(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
|
|||||||
+12
-11
@@ -31,9 +31,10 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.model.api.converters.ConvertEbookToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertEbookToPdfRequest;
|
||||||
@@ -48,14 +49,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertEbookToPDFControllerTest {
|
class ConvertEbookToPDFControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,14 +147,13 @@ class ConvertEbookToPDFControllerTest {
|
|||||||
return execResult;
|
return execResult;
|
||||||
});
|
});
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("result".getBytes());
|
||||||
streamingOk("result".getBytes());
|
|
||||||
wr.when(() -> WebResponseUtils.pdfFileToWebResponse(any(TempFile.class), anyString()))
|
wr.when(() -> WebResponseUtils.pdfFileToWebResponse(any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
gu.when(() -> GeneralUtils.generateFilename("ebook.epub", "_convertedToPDF.pdf"))
|
gu.when(() -> GeneralUtils.generateFilename("ebook.epub", "_convertedToPDF.pdf"))
|
||||||
.thenReturn("ebook_convertedToPDF.pdf");
|
.thenReturn("ebook_convertedToPDF.pdf");
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEbookToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEbookToPdf(request);
|
||||||
|
|
||||||
assertSame(expectedResponse, response);
|
assertSame(expectedResponse, response);
|
||||||
|
|
||||||
@@ -262,11 +263,11 @@ class ConvertEbookToPDFControllerTest {
|
|||||||
gu.when(() -> GeneralUtils.optimizePdfWithGhostscript(Mockito.any(byte[].class)))
|
gu.when(() -> GeneralUtils.optimizePdfWithGhostscript(Mockito.any(byte[].class)))
|
||||||
.thenReturn(optimizedBytes);
|
.thenReturn(optimizedBytes);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(optimizedBytes);
|
ResponseEntity<Resource> expectedResponse = streamingOk(optimizedBytes);
|
||||||
wr.when(() -> WebResponseUtils.pdfFileToWebResponse(any(TempFile.class), anyString()))
|
wr.when(() -> WebResponseUtils.pdfFileToWebResponse(any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEbookToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEbookToPdf(request);
|
||||||
|
|
||||||
assertSame(expectedResponse, response);
|
assertSame(expectedResponse, response);
|
||||||
gu.verify(() -> GeneralUtils.optimizePdfWithGhostscript(Mockito.any(byte[].class)));
|
gu.verify(() -> GeneralUtils.optimizePdfWithGhostscript(Mockito.any(byte[].class)));
|
||||||
|
|||||||
+21
-19
@@ -23,11 +23,12 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.api.converters.EmlToPdfRequest;
|
import stirling.software.common.model.api.converters.EmlToPdfRequest;
|
||||||
@@ -40,14 +41,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertEmlToPDFTest {
|
class ConvertEmlToPDFTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +84,7 @@ class ConvertEmlToPDFTest {
|
|||||||
EmlToPdfRequest request = new EmlToPdfRequest();
|
EmlToPdfRequest request = new EmlToPdfRequest();
|
||||||
request.setFileInput(emptyFile);
|
request.setFileInput(emptyFile);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -98,7 +100,7 @@ class ConvertEmlToPDFTest {
|
|||||||
EmlToPdfRequest request = new EmlToPdfRequest();
|
EmlToPdfRequest request = new EmlToPdfRequest();
|
||||||
request.setFileInput(file);
|
request.setFileInput(file);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -113,7 +115,7 @@ class ConvertEmlToPDFTest {
|
|||||||
EmlToPdfRequest request = new EmlToPdfRequest();
|
EmlToPdfRequest request = new EmlToPdfRequest();
|
||||||
request.setFileInput(file);
|
request.setFileInput(file);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -126,7 +128,7 @@ class ConvertEmlToPDFTest {
|
|||||||
EmlToPdfRequest request = new EmlToPdfRequest();
|
EmlToPdfRequest request = new EmlToPdfRequest();
|
||||||
request.setFileInput(file);
|
request.setFileInput(file);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -146,7 +148,7 @@ class ConvertEmlToPDFTest {
|
|||||||
|
|
||||||
when(runtimePathConfig.getWeasyPrintPath()).thenReturn("/usr/bin/weasyprint");
|
when(runtimePathConfig.getWeasyPrintPath()).thenReturn("/usr/bin/weasyprint");
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(pdfBytes);
|
ResponseEntity<Resource> expectedResponse = streamingOk(pdfBytes);
|
||||||
|
|
||||||
try (MockedStatic<EmlToPdf> emlMock = Mockito.mockStatic(EmlToPdf.class);
|
try (MockedStatic<EmlToPdf> emlMock = Mockito.mockStatic(EmlToPdf.class);
|
||||||
MockedStatic<WebResponseUtils> wrMock =
|
MockedStatic<WebResponseUtils> wrMock =
|
||||||
@@ -170,7 +172,7 @@ class ConvertEmlToPDFTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertArrayEquals(pdfBytes, drainBody(response));
|
assertArrayEquals(pdfBytes, drainBody(response));
|
||||||
@@ -188,7 +190,7 @@ class ConvertEmlToPDFTest {
|
|||||||
request.setFileInput(file);
|
request.setFileInput(file);
|
||||||
request.setDownloadHtml(true);
|
request.setDownloadHtml(true);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse =
|
||||||
streamingOk(htmlContent.getBytes(StandardCharsets.UTF_8));
|
streamingOk(htmlContent.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
try (MockedStatic<EmlToPdf> emlMock = Mockito.mockStatic(EmlToPdf.class);
|
try (MockedStatic<EmlToPdf> emlMock = Mockito.mockStatic(EmlToPdf.class);
|
||||||
@@ -209,7 +211,7 @@ class ConvertEmlToPDFTest {
|
|||||||
any(TempFile.class), anyString(), any(MediaType.class)))
|
any(TempFile.class), anyString(), any(MediaType.class)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -235,7 +237,7 @@ class ConvertEmlToPDFTest {
|
|||||||
eq(customHtmlSanitizer)))
|
eq(customHtmlSanitizer)))
|
||||||
.thenThrow(new IOException("Parse error"));
|
.thenThrow(new IOException("Parse error"));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
|
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -263,7 +265,7 @@ class ConvertEmlToPDFTest {
|
|||||||
any(), any(), any(), any(), any(), any(), any()))
|
any(), any(), any(), any(), any(), any(), any()))
|
||||||
.thenReturn(null);
|
.thenReturn(null);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
|
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -287,7 +289,7 @@ class ConvertEmlToPDFTest {
|
|||||||
|
|
||||||
when(runtimePathConfig.getWeasyPrintPath()).thenReturn("/usr/bin/weasyprint");
|
when(runtimePathConfig.getWeasyPrintPath()).thenReturn("/usr/bin/weasyprint");
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(pdfBytes);
|
ResponseEntity<Resource> expectedResponse = streamingOk(pdfBytes);
|
||||||
|
|
||||||
try (MockedStatic<EmlToPdf> emlMock = Mockito.mockStatic(EmlToPdf.class);
|
try (MockedStatic<EmlToPdf> emlMock = Mockito.mockStatic(EmlToPdf.class);
|
||||||
MockedStatic<WebResponseUtils> wrMock =
|
MockedStatic<WebResponseUtils> wrMock =
|
||||||
@@ -305,7 +307,7 @@ class ConvertEmlToPDFTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -330,7 +332,7 @@ class ConvertEmlToPDFTest {
|
|||||||
any(), any(), any(), any(), any(), any(), any()))
|
any(), any(), any(), any(), any(), any(), any()))
|
||||||
.thenThrow(new InterruptedException("interrupted"));
|
.thenThrow(new InterruptedException("interrupted"));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertEmlToPdf(request);
|
ResponseEntity<Resource> response = controller.convertEmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
|
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
|
|||||||
+12
-10
@@ -20,10 +20,11 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
|
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
|
||||||
@@ -37,14 +38,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertHtmlToPDFTest {
|
class ConvertHtmlToPDFTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +106,7 @@ class ConvertHtmlToPDFTest {
|
|||||||
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes))
|
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes))
|
||||||
.thenReturn(processedPdf);
|
.thenReturn(processedPdf);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(processedPdf);
|
ResponseEntity<Resource> expectedResponse = streamingOk(processedPdf);
|
||||||
|
|
||||||
try (MockedStatic<FileToPdf> ftpMock = Mockito.mockStatic(FileToPdf.class);
|
try (MockedStatic<FileToPdf> ftpMock = Mockito.mockStatic(FileToPdf.class);
|
||||||
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
||||||
@@ -131,7 +133,7 @@ class ConvertHtmlToPDFTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.HtmlToPdf(request);
|
ResponseEntity<Resource> response = controller.HtmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -152,7 +154,7 @@ class ConvertHtmlToPDFTest {
|
|||||||
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes))
|
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes))
|
||||||
.thenReturn(processedPdf);
|
.thenReturn(processedPdf);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(processedPdf);
|
ResponseEntity<Resource> expectedResponse = streamingOk(processedPdf);
|
||||||
|
|
||||||
try (MockedStatic<FileToPdf> ftpMock = Mockito.mockStatic(FileToPdf.class);
|
try (MockedStatic<FileToPdf> ftpMock = Mockito.mockStatic(FileToPdf.class);
|
||||||
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
||||||
@@ -179,7 +181,7 @@ class ConvertHtmlToPDFTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.HtmlToPdf(request);
|
ResponseEntity<Resource> response = controller.HtmlToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -12,9 +12,10 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
|
||||||
@@ -26,14 +27,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertImgPDFControllerTest {
|
class ConvertImgPDFControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-8
@@ -22,10 +22,11 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
import stirling.software.common.model.api.GeneralFile;
|
import stirling.software.common.model.api.GeneralFile;
|
||||||
@@ -39,14 +40,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertMarkdownToPdfTest {
|
class ConvertMarkdownToPdfTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +108,7 @@ class ConvertMarkdownToPdfTest {
|
|||||||
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(any(byte[].class)))
|
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(any(byte[].class)))
|
||||||
.thenReturn(processedPdf);
|
.thenReturn(processedPdf);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(processedPdf);
|
ResponseEntity<Resource> expectedResponse = streamingOk(processedPdf);
|
||||||
|
|
||||||
try (MockedStatic<FileToPdf> ftpMock = Mockito.mockStatic(FileToPdf.class);
|
try (MockedStatic<FileToPdf> ftpMock = Mockito.mockStatic(FileToPdf.class);
|
||||||
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
||||||
@@ -133,7 +135,7 @@ class ConvertMarkdownToPdfTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.markdownToPdf(generalFile);
|
ResponseEntity<Resource> response = controller.markdownToPdf(generalFile);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-9
@@ -30,10 +30,11 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.model.api.converters.ConvertPdfToEpubRequest;
|
import stirling.software.SPDF.model.api.converters.ConvertPdfToEpubRequest;
|
||||||
@@ -48,14 +49,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertPDFToEpubControllerTest {
|
class ConvertPDFToEpubControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +144,7 @@ class ConvertPDFToEpubControllerTest {
|
|||||||
|
|
||||||
gu.when(() -> GeneralUtils.generateFilename("novel.pdf", "_convertedToEPUB.epub"))
|
gu.when(() -> GeneralUtils.generateFilename("novel.pdf", "_convertedToEPUB.epub"))
|
||||||
.thenReturn("novel_convertedToEPUB.epub");
|
.thenReturn("novel_convertedToEPUB.epub");
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertPdfToEpub(request);
|
ResponseEntity<Resource> response = controller.convertPdfToEpub(request);
|
||||||
|
|
||||||
List<String> command = commandCaptor.getValue();
|
List<String> command = commandCaptor.getValue();
|
||||||
assertEquals(13, command.size());
|
assertEquals(13, command.size());
|
||||||
@@ -234,7 +236,7 @@ class ConvertPDFToEpubControllerTest {
|
|||||||
|
|
||||||
gu.when(() -> GeneralUtils.generateFilename("story.pdf", "_convertedToEPUB.epub"))
|
gu.when(() -> GeneralUtils.generateFilename("story.pdf", "_convertedToEPUB.epub"))
|
||||||
.thenReturn("story_convertedToEPUB.epub");
|
.thenReturn("story_convertedToEPUB.epub");
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertPdfToEpub(request);
|
ResponseEntity<Resource> response = controller.convertPdfToEpub(request);
|
||||||
|
|
||||||
List<String> command = commandCaptor.getValue();
|
List<String> command = commandCaptor.getValue();
|
||||||
assertTrue(command.stream().noneMatch(arg -> "--chapter".equals(arg)));
|
assertTrue(command.stream().noneMatch(arg -> "--chapter".equals(arg)));
|
||||||
@@ -319,7 +321,7 @@ class ConvertPDFToEpubControllerTest {
|
|||||||
|
|
||||||
gu.when(() -> GeneralUtils.generateFilename("book.pdf", "_convertedToAZW3.azw3"))
|
gu.when(() -> GeneralUtils.generateFilename("book.pdf", "_convertedToAZW3.azw3"))
|
||||||
.thenReturn("book_convertedToAZW3.azw3");
|
.thenReturn("book_convertedToAZW3.azw3");
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertPdfToEpub(request);
|
ResponseEntity<Resource> response = controller.convertPdfToEpub(request);
|
||||||
|
|
||||||
List<String> command = commandCaptor.getValue();
|
List<String> command = commandCaptor.getValue();
|
||||||
assertEquals("ebook-convert", command.get(0));
|
assertEquals("ebook-convert", command.get(0));
|
||||||
|
|||||||
+2
-2
@@ -20,10 +20,10 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -81,7 +81,7 @@ class ConvertPDFToExcelControllerTest {
|
|||||||
Mockito.eq(true)))
|
Mockito.eq(true)))
|
||||||
.thenReturn(List.of(1));
|
.thenReturn(List.of(1));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.pdfToExcel(request);
|
ResponseEntity<Resource> response = controller.pdfToExcel(request);
|
||||||
|
|
||||||
// tabula may or may not find tables in an empty page
|
// tabula may or may not find tables in an empty page
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
|
|||||||
+11
-12
@@ -21,10 +21,11 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToPresentationRequest;
|
import stirling.software.SPDF.model.api.converters.PdfToPresentationRequest;
|
||||||
import stirling.software.SPDF.model.api.converters.PdfToTextOrRTFRequest;
|
import stirling.software.SPDF.model.api.converters.PdfToTextOrRTFRequest;
|
||||||
@@ -40,14 +41,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertPDFToOfficeTest {
|
class ConvertPDFToOfficeTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,8 +87,7 @@ class ConvertPDFToOfficeTest {
|
|||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
request.setOutputFormat("pptx");
|
request.setOutputFormat("pptx");
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("pptx-content".getBytes());
|
||||||
streamingOk("pptx-content".getBytes());
|
|
||||||
|
|
||||||
try (MockedStatic<PDFToFile> mock =
|
try (MockedStatic<PDFToFile> mock =
|
||||||
Mockito.mockStatic(PDFToFile.class, Mockito.CALLS_REAL_METHODS)) {
|
Mockito.mockStatic(PDFToFile.class, Mockito.CALLS_REAL_METHODS)) {
|
||||||
@@ -115,8 +116,7 @@ class ConvertPDFToOfficeTest {
|
|||||||
realDoc.addPage(new org.apache.pdfbox.pdmodel.PDPage());
|
realDoc.addPage(new org.apache.pdfbox.pdmodel.PDPage());
|
||||||
when(pdfDocumentFactory.load(pdfFile)).thenReturn(realDoc);
|
when(pdfDocumentFactory.load(pdfFile)).thenReturn(realDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("text content".getBytes());
|
||||||
streamingOk("text content".getBytes());
|
|
||||||
|
|
||||||
try (MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
try (MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
||||||
MockedStatic<WebResponseUtils> wrMock =
|
MockedStatic<WebResponseUtils> wrMock =
|
||||||
@@ -131,8 +131,7 @@ class ConvertPDFToOfficeTest {
|
|||||||
any(TempFile.class), anyString(), any(MediaType.class)))
|
any(TempFile.class), anyString(), any(MediaType.class)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.processPdfToRTForTXT(request);
|
||||||
controller.processPdfToRTForTXT(request);
|
|
||||||
|
|
||||||
assertSame(expectedResponse, response);
|
assertSame(expectedResponse, response);
|
||||||
}
|
}
|
||||||
|
|||||||
+65
-20
@@ -4,16 +4,18 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.lenient;
|
import static org.mockito.Mockito.lenient;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@@ -22,11 +24,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.service.PdfJsonConversionService;
|
import stirling.software.SPDF.service.PdfJsonConversionService;
|
||||||
import stirling.software.common.model.api.GeneralFile;
|
import stirling.software.common.model.api.GeneralFile;
|
||||||
@@ -58,10 +60,11 @@ class ConvertPdfJsonControllerTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws IOException {
|
||||||
throws IOException {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream in = response.getBody().getInputStream()) {
|
||||||
|
in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,10 +85,17 @@ class ConvertPdfJsonControllerTest {
|
|||||||
PDFFile request = new PDFFile();
|
PDFFile request = new PDFFile();
|
||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
|
|
||||||
when(pdfJsonConversionService.convertPdfToJson(pdfFile, false)).thenReturn(jsonBytes);
|
// Service writes directly to the OutputStream passed by the controller
|
||||||
|
doAnswer(
|
||||||
|
inv -> {
|
||||||
|
OutputStream os = inv.getArgument(2, OutputStream.class);
|
||||||
|
os.write(jsonBytes);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.when(pdfJsonConversionService)
|
||||||
|
.convertPdfToJson(eq(pdfFile), eq(false), any(OutputStream.class));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.convertPdfToJson(request, false);
|
||||||
controller.convertPdfToJson(request, false);
|
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertNotNull(response.getBody());
|
assertNotNull(response.getBody());
|
||||||
@@ -100,12 +110,20 @@ class ConvertPdfJsonControllerTest {
|
|||||||
PDFFile request = new PDFFile();
|
PDFFile request = new PDFFile();
|
||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
|
|
||||||
when(pdfJsonConversionService.convertPdfToJson(pdfFile, true)).thenReturn(jsonBytes);
|
doAnswer(
|
||||||
|
inv -> {
|
||||||
|
OutputStream os = inv.getArgument(2, OutputStream.class);
|
||||||
|
os.write(jsonBytes);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.when(pdfJsonConversionService)
|
||||||
|
.convertPdfToJson(eq(pdfFile), eq(true), any(OutputStream.class));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertPdfToJson(request, true);
|
ResponseEntity<Resource> response = controller.convertPdfToJson(request, true);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
verify(pdfJsonConversionService).convertPdfToJson(pdfFile, true);
|
verify(pdfJsonConversionService)
|
||||||
|
.convertPdfToJson(eq(pdfFile), eq(true), any(OutputStream.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -125,9 +143,16 @@ class ConvertPdfJsonControllerTest {
|
|||||||
GeneralFile request = new GeneralFile();
|
GeneralFile request = new GeneralFile();
|
||||||
request.setFileInput(jsonFile);
|
request.setFileInput(jsonFile);
|
||||||
|
|
||||||
when(pdfJsonConversionService.convertJsonToPdf(jsonFile)).thenReturn(pdfBytes);
|
doAnswer(
|
||||||
|
inv -> {
|
||||||
|
OutputStream os = inv.getArgument(1, OutputStream.class);
|
||||||
|
os.write(pdfBytes);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.when(pdfJsonConversionService)
|
||||||
|
.convertJsonToPdf(eq(jsonFile), any(OutputStream.class));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertJsonToPdf(request);
|
ResponseEntity<Resource> response = controller.convertJsonToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertNotNull(response.getBody());
|
assertNotNull(response.getBody());
|
||||||
@@ -150,10 +175,16 @@ class ConvertPdfJsonControllerTest {
|
|||||||
PDFFile request = new PDFFile();
|
PDFFile request = new PDFFile();
|
||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
|
|
||||||
when(pdfJsonConversionService.extractDocumentMetadata(eq(pdfFile), any(String.class)))
|
doAnswer(
|
||||||
.thenReturn(jsonBytes);
|
inv -> {
|
||||||
|
OutputStream os = inv.getArgument(2, OutputStream.class);
|
||||||
|
os.write(jsonBytes);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.when(pdfJsonConversionService)
|
||||||
|
.extractDocumentMetadata(eq(pdfFile), any(String.class), any(OutputStream.class));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractPdfMetadata(request);
|
ResponseEntity<Resource> response = controller.extractPdfMetadata(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertEquals(MediaType.APPLICATION_JSON, response.getHeaders().getContentType());
|
assertEquals(MediaType.APPLICATION_JSON, response.getHeaders().getContentType());
|
||||||
@@ -175,9 +206,16 @@ class ConvertPdfJsonControllerTest {
|
|||||||
byte[] jsonBytes = "{\"content\":[]}".getBytes();
|
byte[] jsonBytes = "{\"content\":[]}".getBytes();
|
||||||
String jobId = "test-job-id";
|
String jobId = "test-job-id";
|
||||||
|
|
||||||
when(pdfJsonConversionService.extractSinglePage(jobId, 1)).thenReturn(jsonBytes);
|
doAnswer(
|
||||||
|
inv -> {
|
||||||
|
OutputStream os = inv.getArgument(2, OutputStream.class);
|
||||||
|
os.write(jsonBytes);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.when(pdfJsonConversionService)
|
||||||
|
.extractSinglePage(eq(jobId), anyInt(), any(OutputStream.class));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractSinglePage(jobId, 1);
|
ResponseEntity<Resource> response = controller.extractSinglePage(jobId, 1);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertNotNull(response.getBody());
|
assertNotNull(response.getBody());
|
||||||
@@ -188,9 +226,16 @@ class ConvertPdfJsonControllerTest {
|
|||||||
byte[] jsonBytes = "{\"fonts\":[]}".getBytes();
|
byte[] jsonBytes = "{\"fonts\":[]}".getBytes();
|
||||||
String jobId = "test-job-id";
|
String jobId = "test-job-id";
|
||||||
|
|
||||||
when(pdfJsonConversionService.extractPageFonts(jobId, 1)).thenReturn(jsonBytes);
|
doAnswer(
|
||||||
|
inv -> {
|
||||||
|
OutputStream os = inv.getArgument(2, OutputStream.class);
|
||||||
|
os.write(jsonBytes);
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.when(pdfJsonConversionService)
|
||||||
|
.extractPageFonts(eq(jobId), anyInt(), any(OutputStream.class));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractPageFonts(jobId, 1);
|
ResponseEntity<Resource> response = controller.extractPageFonts(jobId, 1);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
assertNotNull(response.getBody());
|
assertNotNull(response.getBody());
|
||||||
|
|||||||
+18
-16
@@ -21,10 +21,11 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.SvgToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.SvgToPdfRequest;
|
||||||
import stirling.software.SPDF.utils.SvgToPdf;
|
import stirling.software.SPDF.utils.SvgToPdf;
|
||||||
@@ -37,14 +38,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ConvertSvgToPDFTest {
|
class ConvertSvgToPDFTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +77,7 @@ class ConvertSvgToPDFTest {
|
|||||||
SvgToPdfRequest request = new SvgToPdfRequest();
|
SvgToPdfRequest request = new SvgToPdfRequest();
|
||||||
request.setFileInput(null);
|
request.setFileInput(null);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -88,7 +90,7 @@ class ConvertSvgToPDFTest {
|
|||||||
SvgToPdfRequest request = new SvgToPdfRequest();
|
SvgToPdfRequest request = new SvgToPdfRequest();
|
||||||
request.setFileInput(new MockMultipartFile[0]);
|
request.setFileInput(new MockMultipartFile[0]);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -102,7 +104,7 @@ class ConvertSvgToPDFTest {
|
|||||||
request.setFileInput(new MockMultipartFile[] {txtFile});
|
request.setFileInput(new MockMultipartFile[] {txtFile});
|
||||||
request.setCombineIntoSinglePdf(false);
|
request.setCombineIntoSinglePdf(false);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
assertTrue(
|
assertTrue(
|
||||||
@@ -118,7 +120,7 @@ class ConvertSvgToPDFTest {
|
|||||||
request.setFileInput(new MockMultipartFile[] {emptyFile});
|
request.setFileInput(new MockMultipartFile[] {emptyFile});
|
||||||
request.setCombineIntoSinglePdf(false);
|
request.setCombineIntoSinglePdf(false);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -141,7 +143,7 @@ class ConvertSvgToPDFTest {
|
|||||||
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes))
|
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes))
|
||||||
.thenReturn(processedPdf);
|
.thenReturn(processedPdf);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(processedPdf);
|
ResponseEntity<Resource> expectedResponse = streamingOk(processedPdf);
|
||||||
|
|
||||||
try (MockedStatic<SvgToPdf> svgMock = Mockito.mockStatic(SvgToPdf.class);
|
try (MockedStatic<SvgToPdf> svgMock = Mockito.mockStatic(SvgToPdf.class);
|
||||||
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
||||||
@@ -159,7 +161,7 @@ class ConvertSvgToPDFTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -188,7 +190,7 @@ class ConvertSvgToPDFTest {
|
|||||||
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(combinedPdf))
|
when(pdfDocumentFactory.createNewBytesBasedOnOldDocument(combinedPdf))
|
||||||
.thenReturn(processedPdf);
|
.thenReturn(processedPdf);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(processedPdf);
|
ResponseEntity<Resource> expectedResponse = streamingOk(processedPdf);
|
||||||
|
|
||||||
try (MockedStatic<SvgToPdf> svgMock = Mockito.mockStatic(SvgToPdf.class);
|
try (MockedStatic<SvgToPdf> svgMock = Mockito.mockStatic(SvgToPdf.class);
|
||||||
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
MockedStatic<GeneralUtils> guMock = Mockito.mockStatic(GeneralUtils.class);
|
||||||
@@ -206,7 +208,7 @@ class ConvertSvgToPDFTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -221,7 +223,7 @@ class ConvertSvgToPDFTest {
|
|||||||
request.setFileInput(new MockMultipartFile[] {nullNameFile});
|
request.setFileInput(new MockMultipartFile[] {nullNameFile});
|
||||||
request.setCombineIntoSinglePdf(false);
|
request.setCombineIntoSinglePdf(false);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -238,7 +240,7 @@ class ConvertSvgToPDFTest {
|
|||||||
|
|
||||||
when(svgSanitizer.sanitize(svgContent)).thenThrow(new IOException("sanitization error"));
|
when(svgSanitizer.sanitize(svgContent)).thenThrow(new IOException("sanitization error"));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.convertSvgToPdf(request);
|
ResponseEntity<Resource> response = controller.convertSvgToPdf(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -30,12 +30,13 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.UrlToPdfRequest;
|
||||||
import stirling.software.common.configuration.RuntimePathConfig;
|
import stirling.software.common.configuration.RuntimePathConfig;
|
||||||
@@ -49,14 +50,15 @@ import stirling.software.common.util.TempFile;
|
|||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
|
|
||||||
public class ConvertWebsiteToPdfTest {
|
public class ConvertWebsiteToPdfTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -24,10 +24,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.config.EndpointConfiguration;
|
import stirling.software.SPDF.config.EndpointConfiguration;
|
||||||
import stirling.software.SPDF.model.api.converters.PdfVectorExportRequest;
|
import stirling.software.SPDF.model.api.converters.PdfVectorExportRequest;
|
||||||
@@ -122,8 +122,7 @@ class PdfVectorExportControllerTest {
|
|||||||
PdfVectorExportRequest request = new PdfVectorExportRequest();
|
PdfVectorExportRequest request = new PdfVectorExportRequest();
|
||||||
request.setFileInput(file);
|
request.setFileInput(file);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.convertGhostscriptInputsToPdf(request);
|
||||||
controller.convertGhostscriptInputsToPdf(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
|
||||||
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
|
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
|
||||||
@@ -140,13 +139,14 @@ class PdfVectorExportControllerTest {
|
|||||||
PdfVectorExportRequest request = new PdfVectorExportRequest();
|
PdfVectorExportRequest request = new PdfVectorExportRequest();
|
||||||
request.setFileInput(file);
|
request.setFileInput(file);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.convertGhostscriptInputsToPdf(request);
|
||||||
controller.convertGhostscriptInputsToPdf(request);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
|
||||||
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
|
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
|
||||||
java.io.ByteArrayOutputStream baosVerify = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baosVerify = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baosVerify);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baosVerify);
|
||||||
|
}
|
||||||
assertThat(baosVerify.toByteArray()).contains(content);
|
assertThat(baosVerify.toByteArray()).contains(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-12
@@ -13,11 +13,12 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.PDFComparisonAndCount;
|
import stirling.software.SPDF.model.api.PDFComparisonAndCount;
|
||||||
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
import stirling.software.SPDF.model.api.PDFWithPageNums;
|
||||||
@@ -32,14 +33,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class FilterControllerTest {
|
class FilterControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ class FilterControllerTest {
|
|||||||
PDDocument mockDoc = mock(PDDocument.class);
|
PDDocument mockDoc = mock(PDDocument.class);
|
||||||
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDoc);
|
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(new byte[] {1, 2, 3});
|
ResponseEntity<Resource> expectedResponse = streamingOk(new byte[] {1, 2, 3});
|
||||||
|
|
||||||
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class);
|
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class);
|
||||||
MockedStatic<WebResponseUtils> webMock = mockStatic(WebResponseUtils.class)) {
|
MockedStatic<WebResponseUtils> webMock = mockStatic(WebResponseUtils.class)) {
|
||||||
@@ -84,7 +86,7 @@ class FilterControllerTest {
|
|||||||
mockDoc, "test.pdf", tempFileManager))
|
mockDoc, "test.pdf", tempFileManager))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> result = filterController.containsText(request);
|
ResponseEntity<Resource> result = filterController.containsText(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||||
assertArrayEquals(new byte[] {1, 2, 3}, drainBody(result));
|
assertArrayEquals(new byte[] {1, 2, 3}, drainBody(result));
|
||||||
@@ -104,7 +106,7 @@ class FilterControllerTest {
|
|||||||
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class)) {
|
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class)) {
|
||||||
pdfUtilsMock.when(() -> PdfUtils.hasText(mockDoc, "all", "missing")).thenReturn(false);
|
pdfUtilsMock.when(() -> PdfUtils.hasText(mockDoc, "all", "missing")).thenReturn(false);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> result = filterController.containsText(request);
|
ResponseEntity<Resource> result = filterController.containsText(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.NO_CONTENT, result.getStatusCode());
|
assertEquals(HttpStatus.NO_CONTENT, result.getStatusCode());
|
||||||
assertNull(result.getBody());
|
assertNull(result.getBody());
|
||||||
@@ -122,7 +124,7 @@ class FilterControllerTest {
|
|||||||
PDDocument mockDoc = mock(PDDocument.class);
|
PDDocument mockDoc = mock(PDDocument.class);
|
||||||
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDoc);
|
when(pdfDocumentFactory.load(mockFile)).thenReturn(mockDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(new byte[] {4, 5, 6});
|
ResponseEntity<Resource> expectedResponse = streamingOk(new byte[] {4, 5, 6});
|
||||||
|
|
||||||
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class);
|
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class);
|
||||||
MockedStatic<WebResponseUtils> webMock = mockStatic(WebResponseUtils.class)) {
|
MockedStatic<WebResponseUtils> webMock = mockStatic(WebResponseUtils.class)) {
|
||||||
@@ -134,7 +136,7 @@ class FilterControllerTest {
|
|||||||
mockDoc, "test.pdf", tempFileManager))
|
mockDoc, "test.pdf", tempFileManager))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> result = filterController.containsImage(request);
|
ResponseEntity<Resource> result = filterController.containsImage(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.OK, result.getStatusCode());
|
assertEquals(HttpStatus.OK, result.getStatusCode());
|
||||||
assertArrayEquals(new byte[] {4, 5, 6}, drainBody(result));
|
assertArrayEquals(new byte[] {4, 5, 6}, drainBody(result));
|
||||||
@@ -153,7 +155,7 @@ class FilterControllerTest {
|
|||||||
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class)) {
|
try (MockedStatic<PdfUtils> pdfUtilsMock = mockStatic(PdfUtils.class)) {
|
||||||
pdfUtilsMock.when(() -> PdfUtils.hasImages(mockDoc, "1")).thenReturn(false);
|
pdfUtilsMock.when(() -> PdfUtils.hasImages(mockDoc, "1")).thenReturn(false);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> result = filterController.containsImage(request);
|
ResponseEntity<Resource> result = filterController.containsImage(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.NO_CONTENT, result.getStatusCode());
|
assertEquals(HttpStatus.NO_CONTENT, result.getStatusCode());
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-12
@@ -22,10 +22,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
import stirling.software.common.util.TempFile;
|
import stirling.software.common.util.TempFile;
|
||||||
@@ -37,14 +38,15 @@ import tools.jackson.databind.json.JsonMapper;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
@DisplayName("FormFillController Tests")
|
@DisplayName("FormFillController Tests")
|
||||||
class FormFillControllerTest {
|
class FormFillControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,8 +234,7 @@ class FormFillControllerTest {
|
|||||||
when(pdfDocumentFactory.load(eq(file))).thenReturn(doc);
|
when(pdfDocumentFactory.load(eq(file))).thenReturn(doc);
|
||||||
|
|
||||||
byte[] payload = "{\"field1\":\"value1\"}".getBytes();
|
byte[] payload = "{\"field1\":\"value1\"}".getBytes();
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.fillForm(file, payload, false);
|
||||||
controller.fillForm(file, payload, false);
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
@@ -246,7 +247,7 @@ class FormFillControllerTest {
|
|||||||
PDDocument doc = createMinimalPdf();
|
PDDocument doc = createMinimalPdf();
|
||||||
when(pdfDocumentFactory.load(eq(file))).thenReturn(doc);
|
when(pdfDocumentFactory.load(eq(file))).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.fillForm(file, null, false);
|
ResponseEntity<Resource> response = controller.fillForm(file, null, false);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -287,7 +288,7 @@ class FormFillControllerTest {
|
|||||||
when(pdfDocumentFactory.load(eq(file))).thenReturn(doc);
|
when(pdfDocumentFactory.load(eq(file))).thenReturn(doc);
|
||||||
|
|
||||||
byte[] payload = "[\"field1\"]".getBytes();
|
byte[] payload = "[\"field1\"]".getBytes();
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.deleteFields(file, payload);
|
ResponseEntity<Resource> response = controller.deleteFields(file, payload);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -323,8 +324,7 @@ class FormFillControllerTest {
|
|||||||
String json =
|
String json =
|
||||||
"[{\"targetName\":\"f1\",\"name\":null,\"label\":null,\"type\":null,"
|
"[{\"targetName\":\"f1\",\"name\":null,\"label\":null,\"type\":null,"
|
||||||
+ "\"required\":null,\"multiSelect\":null,\"options\":null,\"defaultValue\":\"newVal\",\"tooltip\":null}]";
|
+ "\"required\":null,\"multiSelect\":null,\"options\":null,\"defaultValue\":\"newVal\",\"tooltip\":null}]";
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.modifyFields(file, json.getBytes());
|
||||||
controller.modifyFields(file, json.getBytes());
|
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-14
@@ -17,12 +17,13 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.AddAttachmentRequest;
|
import stirling.software.SPDF.model.api.misc.AddAttachmentRequest;
|
||||||
import stirling.software.SPDF.service.AttachmentServiceInterface;
|
import stirling.software.SPDF.service.AttachmentServiceInterface;
|
||||||
@@ -33,14 +34,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class AttachmentControllerTest {
|
class AttachmentControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,8 +102,7 @@ class AttachmentControllerTest {
|
|||||||
List<MultipartFile> attachments = List.of(attachment1, attachment2);
|
List<MultipartFile> attachments = List.of(attachment1, attachment2);
|
||||||
request.setAttachments(attachments);
|
request.setAttachments(attachments);
|
||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("modified PDF content".getBytes());
|
||||||
streamingOk("modified PDF content".getBytes());
|
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(request, false)).thenReturn(mockDocument);
|
when(pdfDocumentFactory.load(request, false)).thenReturn(mockDocument);
|
||||||
when(pdfAttachmentService.addAttachment(mockDocument, attachments))
|
when(pdfAttachmentService.addAttachment(mockDocument, attachments))
|
||||||
@@ -118,8 +119,7 @@ class AttachmentControllerTest {
|
|||||||
any(TempFileManager.class)))
|
any(TempFileManager.class)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = attachmentController.addAttachments(request);
|
||||||
attachmentController.addAttachments(request);
|
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -134,8 +134,7 @@ class AttachmentControllerTest {
|
|||||||
List<MultipartFile> attachments = List.of(attachment1);
|
List<MultipartFile> attachments = List.of(attachment1);
|
||||||
request.setAttachments(attachments);
|
request.setAttachments(attachments);
|
||||||
request.setFileInput(pdfFile);
|
request.setFileInput(pdfFile);
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("modified PDF content".getBytes());
|
||||||
streamingOk("modified PDF content".getBytes());
|
|
||||||
|
|
||||||
when(pdfDocumentFactory.load(request, false)).thenReturn(mockDocument);
|
when(pdfDocumentFactory.load(request, false)).thenReturn(mockDocument);
|
||||||
when(pdfAttachmentService.addAttachment(mockDocument, attachments))
|
when(pdfAttachmentService.addAttachment(mockDocument, attachments))
|
||||||
@@ -152,8 +151,7 @@ class AttachmentControllerTest {
|
|||||||
any(TempFileManager.class)))
|
any(TempFileManager.class)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = attachmentController.addAttachments(request);
|
||||||
attachmentController.addAttachments(request);
|
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
|||||||
+15
-13
@@ -23,11 +23,12 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.ExtractHeaderRequest;
|
import stirling.software.SPDF.model.api.misc.ExtractHeaderRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -36,14 +37,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class AutoRenameControllerTest {
|
class AutoRenameControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +103,7 @@ class AutoRenameControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractHeader(request);
|
ResponseEntity<Resource> response = controller.extractHeader(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(drainBody(response)).isNotEmpty();
|
assertThat(drainBody(response)).isNotEmpty();
|
||||||
@@ -127,7 +129,7 @@ class AutoRenameControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractHeader(request);
|
ResponseEntity<Resource> response = controller.extractHeader(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -140,7 +142,7 @@ class AutoRenameControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractHeader(request);
|
ResponseEntity<Resource> response = controller.extractHeader(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -188,7 +190,7 @@ class AutoRenameControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractHeader(request);
|
ResponseEntity<Resource> response = controller.extractHeader(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
// The largest font text should be used as title (URL-encoded in Content-Disposition)
|
// The largest font text should be used as title (URL-encoded in Content-Disposition)
|
||||||
@@ -206,7 +208,7 @@ class AutoRenameControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractHeader(request);
|
ResponseEntity<Resource> response = controller.extractHeader(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
// Should fallback to original filename since header is too long
|
// Should fallback to original filename since header is too long
|
||||||
@@ -222,7 +224,7 @@ class AutoRenameControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractHeader(request);
|
ResponseEntity<Resource> response = controller.extractHeader(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
// Special characters should be sanitized
|
// Special characters should be sanitized
|
||||||
@@ -248,7 +250,7 @@ class AutoRenameControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.extractHeader(request);
|
ResponseEntity<Resource> response = controller.extractHeader(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-12
@@ -23,11 +23,12 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -36,14 +37,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class DecompressPdfControllerTest {
|
class DecompressPdfControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ class DecompressPdfControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.decompressPdf(request);
|
ResponseEntity<Resource> response = controller.decompressPdf(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(drainBody(response)).isNotEmpty();
|
assertThat(drainBody(response)).isNotEmpty();
|
||||||
@@ -116,7 +118,7 @@ class DecompressPdfControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.decompressPdf(request);
|
ResponseEntity<Resource> response = controller.decompressPdf(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(drainBody(response)).isNotEmpty();
|
assertThat(drainBody(response)).isNotEmpty();
|
||||||
@@ -147,7 +149,7 @@ class DecompressPdfControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.decompressPdf(request);
|
ResponseEntity<Resource> response = controller.decompressPdf(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
String contentDisposition = response.getHeaders().getFirst("Content-Disposition");
|
String contentDisposition = response.getHeaders().getFirst("Content-Disposition");
|
||||||
@@ -183,7 +185,7 @@ class DecompressPdfControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.decompressPdf(request);
|
ResponseEntity<Resource> response = controller.decompressPdf(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
try (PDDocument result = Loader.loadPDF(drainBody(response))) {
|
try (PDDocument result = Loader.loadPDF(drainBody(response))) {
|
||||||
@@ -200,7 +202,7 @@ class DecompressPdfControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.decompressPdf(request);
|
ResponseEntity<Resource> response = controller.decompressPdf(request);
|
||||||
|
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
// Decompressed PDF should generally be larger or equal to compressed
|
// Decompressed PDF should generally be larger or equal to compressed
|
||||||
@@ -216,7 +218,7 @@ class DecompressPdfControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.decompressPdf(request);
|
ResponseEntity<Resource> response = controller.decompressPdf(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-13
@@ -25,11 +25,12 @@ import org.junit.jupiter.api.io.TempDir;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
import stirling.software.SPDF.model.api.misc.FlattenRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -38,14 +39,15 @@ import stirling.software.common.util.TempFileManager;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class FlattenControllerTest {
|
class FlattenControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ class FlattenControllerTest {
|
|||||||
PDDocument doc = Loader.loadPDF(file.getBytes());
|
PDDocument doc = Loader.loadPDF(file.getBytes());
|
||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.flatten(request);
|
ResponseEntity<Resource> response = controller.flatten(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(drainBody(response)).isNotEmpty();
|
assertThat(drainBody(response)).isNotEmpty();
|
||||||
@@ -118,7 +120,7 @@ class FlattenControllerTest {
|
|||||||
when(doc.getDocumentCatalog()).thenReturn(catalog);
|
when(doc.getDocumentCatalog()).thenReturn(catalog);
|
||||||
when(catalog.getAcroForm()).thenReturn(null);
|
when(catalog.getAcroForm()).thenReturn(null);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.flatten(request);
|
ResponseEntity<Resource> response = controller.flatten(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
verify(doc).close();
|
verify(doc).close();
|
||||||
@@ -138,7 +140,7 @@ class FlattenControllerTest {
|
|||||||
when(doc.getDocumentCatalog()).thenReturn(catalog);
|
when(doc.getDocumentCatalog()).thenReturn(catalog);
|
||||||
when(catalog.getAcroForm()).thenReturn(form);
|
when(catalog.getAcroForm()).thenReturn(form);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.flatten(request);
|
ResponseEntity<Resource> response = controller.flatten(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
verify(form).flatten();
|
verify(form).flatten();
|
||||||
@@ -170,7 +172,7 @@ class FlattenControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.flatten(request);
|
ResponseEntity<Resource> response = controller.flatten(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(drainBody(response)).isNotEmpty();
|
assertThat(drainBody(response)).isNotEmpty();
|
||||||
@@ -188,7 +190,7 @@ class FlattenControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.flatten(request);
|
ResponseEntity<Resource> response = controller.flatten(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -206,7 +208,7 @@ class FlattenControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.flatten(request);
|
ResponseEntity<Resource> response = controller.flatten(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
@@ -224,7 +226,7 @@ class FlattenControllerTest {
|
|||||||
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
when(pdfDocumentFactory.load(file)).thenReturn(doc);
|
||||||
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
when(pdfDocumentFactory.createNewDocumentBasedOnOldDocument(doc)).thenReturn(newDoc);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.flatten(request);
|
ResponseEntity<Resource> response = controller.flatten(request);
|
||||||
|
|
||||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-19
@@ -23,11 +23,12 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.OverlayImageRequest;
|
import stirling.software.SPDF.model.api.misc.OverlayImageRequest;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -37,14 +38,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class OverlayImageControllerTest {
|
class OverlayImageControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,8 +110,7 @@ class OverlayImageControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("result".getBytes());
|
||||||
streamingOk("result".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -117,7 +118,7 @@ class OverlayImageControllerTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayImage(request);
|
ResponseEntity<Resource> response = controller.overlayImage(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -136,7 +137,7 @@ class OverlayImageControllerTest {
|
|||||||
|
|
||||||
when(pdfDocumentFactory.load(any(byte[].class))).thenThrow(new IOException("bad PDF"));
|
when(pdfDocumentFactory.load(any(byte[].class))).thenThrow(new IOException("bad PDF"));
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayImage(request);
|
ResponseEntity<Resource> response = controller.overlayImage(request);
|
||||||
|
|
||||||
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
|
||||||
}
|
}
|
||||||
@@ -157,8 +158,7 @@ class OverlayImageControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("result".getBytes());
|
||||||
streamingOk("result".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -166,7 +166,7 @@ class OverlayImageControllerTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayImage(request);
|
ResponseEntity<Resource> response = controller.overlayImage(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -189,8 +189,7 @@ class OverlayImageControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("result".getBytes());
|
||||||
streamingOk("result".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -198,7 +197,7 @@ class OverlayImageControllerTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayImage(request);
|
ResponseEntity<Resource> response = controller.overlayImage(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -221,8 +220,7 @@ class OverlayImageControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("result".getBytes());
|
||||||
streamingOk("result".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -231,7 +229,7 @@ class OverlayImageControllerTest {
|
|||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
// Should not throw - coordinates are passed to contentStream.drawImage
|
// Should not throw - coordinates are passed to contentStream.drawImage
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.overlayImage(request);
|
ResponseEntity<Resource> response = controller.overlayImage(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
|||||||
+15
-16
@@ -17,12 +17,13 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.SPDF.model.api.misc.ReplaceAndInvertColorRequest;
|
import stirling.software.SPDF.model.api.misc.ReplaceAndInvertColorRequest;
|
||||||
import stirling.software.SPDF.service.misc.ReplaceAndInvertColorService;
|
import stirling.software.SPDF.service.misc.ReplaceAndInvertColorService;
|
||||||
@@ -34,14 +35,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ReplaceAndInvertColorControllerTest {
|
class ReplaceAndInvertColorControllerTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +98,7 @@ class ReplaceAndInvertColorControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(resultBytes);
|
ResponseEntity<Resource> expectedResponse = streamingOk(resultBytes);
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -104,8 +106,7 @@ class ReplaceAndInvertColorControllerTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.replaceAndInvertColor(request);
|
||||||
controller.replaceAndInvertColor(request);
|
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -132,7 +133,7 @@ class ReplaceAndInvertColorControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(resultBytes);
|
ResponseEntity<Resource> expectedResponse = streamingOk(resultBytes);
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -140,8 +141,7 @@ class ReplaceAndInvertColorControllerTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.replaceAndInvertColor(request);
|
||||||
controller.replaceAndInvertColor(request);
|
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -166,7 +166,7 @@ class ReplaceAndInvertColorControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(resultBytes);
|
ResponseEntity<Resource> expectedResponse = streamingOk(resultBytes);
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -174,8 +174,7 @@ class ReplaceAndInvertColorControllerTest {
|
|||||||
any(TempFile.class), anyString()))
|
any(TempFile.class), anyString()))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response =
|
ResponseEntity<Resource> response = controller.replaceAndInvertColor(request);
|
||||||
controller.replaceAndInvertColor(request);
|
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -205,7 +204,7 @@ class ReplaceAndInvertColorControllerTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse = streamingOk(resultBytes);
|
ResponseEntity<Resource> expectedResponse = streamingOk(resultBytes);
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
|
|||||||
+16
-18
@@ -19,11 +19,12 @@ import org.mockito.InjectMocks;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -33,14 +34,15 @@ import stirling.software.common.util.WebResponseUtils;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
class ShowJavascriptTest {
|
class ShowJavascriptTest {
|
||||||
private static ResponseEntity<StreamingResponseBody> streamingOk(byte[] bytes) {
|
private static ResponseEntity<Resource> streamingOk(byte[] bytes) {
|
||||||
return ResponseEntity.ok(out -> out.write(bytes));
|
return ResponseEntity.ok(new ByteArrayResource(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] drainBody(ResponseEntity<StreamingResponseBody> response)
|
private static byte[] drainBody(ResponseEntity<Resource> response) throws java.io.IOException {
|
||||||
throws java.io.IOException {
|
|
||||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||||
response.getBody().writeTo(baos);
|
try (java.io.InputStream __in = response.getBody().getInputStream()) {
|
||||||
|
__in.transferTo(baos);
|
||||||
|
}
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +88,7 @@ class ShowJavascriptTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("no js".getBytes());
|
||||||
streamingOk("no js".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -97,7 +98,7 @@ class ShowJavascriptTest {
|
|||||||
eq(MediaType.TEXT_PLAIN)))
|
eq(MediaType.TEXT_PLAIN)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = showJavascript.extractHeader(request);
|
ResponseEntity<Resource> response = showJavascript.extractHeader(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
@@ -129,8 +130,7 @@ class ShowJavascriptTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("js content".getBytes());
|
||||||
streamingOk("js content".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -140,7 +140,7 @@ class ShowJavascriptTest {
|
|||||||
eq(MediaType.TEXT_PLAIN)))
|
eq(MediaType.TEXT_PLAIN)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = showJavascript.extractHeader(request);
|
ResponseEntity<Resource> response = showJavascript.extractHeader(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
mockedWebResponse.verify(
|
mockedWebResponse.verify(
|
||||||
@@ -160,8 +160,7 @@ class ShowJavascriptTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("no js".getBytes());
|
||||||
streamingOk("no js".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -171,7 +170,7 @@ class ShowJavascriptTest {
|
|||||||
eq(MediaType.TEXT_PLAIN)))
|
eq(MediaType.TEXT_PLAIN)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = showJavascript.extractHeader(request);
|
ResponseEntity<Resource> response = showJavascript.extractHeader(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
mockedWebResponse.verify(
|
mockedWebResponse.verify(
|
||||||
@@ -200,8 +199,7 @@ class ShowJavascriptTest {
|
|||||||
|
|
||||||
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
try (MockedStatic<WebResponseUtils> mockedWebResponse =
|
||||||
mockStatic(WebResponseUtils.class)) {
|
mockStatic(WebResponseUtils.class)) {
|
||||||
ResponseEntity<StreamingResponseBody> expectedResponse =
|
ResponseEntity<Resource> expectedResponse = streamingOk("no js".getBytes());
|
||||||
streamingOk("no js".getBytes());
|
|
||||||
mockedWebResponse
|
mockedWebResponse
|
||||||
.when(
|
.when(
|
||||||
() ->
|
() ->
|
||||||
@@ -211,7 +209,7 @@ class ShowJavascriptTest {
|
|||||||
eq(MediaType.TEXT_PLAIN)))
|
eq(MediaType.TEXT_PLAIN)))
|
||||||
.thenReturn(expectedResponse);
|
.thenReturn(expectedResponse);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = showJavascript.extractHeader(request);
|
ResponseEntity<Resource> response = showJavascript.extractHeader(request);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
mockedWebResponse.verify(
|
mockedWebResponse.verify(
|
||||||
|
|||||||
+6
-6
@@ -16,9 +16,9 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
|
||||||
|
|
||||||
import stirling.software.common.model.api.PDFFile;
|
import stirling.software.common.model.api.PDFFile;
|
||||||
import stirling.software.common.service.CustomPDFDocumentFactory;
|
import stirling.software.common.service.CustomPDFDocumentFactory;
|
||||||
@@ -67,7 +67,7 @@ class UnlockPDFFormsControllerTest {
|
|||||||
PDFFile file = new PDFFile();
|
PDFFile file = new PDFFile();
|
||||||
file.setFileInput(mockPdfFile);
|
file.setFileInput(mockPdfFile);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.unlockPDFForms(file);
|
ResponseEntity<Resource> response = controller.unlockPDFForms(file);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -85,7 +85,7 @@ class UnlockPDFFormsControllerTest {
|
|||||||
PDFFile file = new PDFFile();
|
PDFFile file = new PDFFile();
|
||||||
file.setFileInput(mockPdfFile);
|
file.setFileInput(mockPdfFile);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.unlockPDFForms(file);
|
ResponseEntity<Resource> response = controller.unlockPDFForms(file);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(200, response.getStatusCode().value());
|
assertEquals(200, response.getStatusCode().value());
|
||||||
@@ -99,7 +99,7 @@ class UnlockPDFFormsControllerTest {
|
|||||||
PDFFile file = new PDFFile();
|
PDFFile file = new PDFFile();
|
||||||
file.setFileInput(mockPdfFile);
|
file.setFileInput(mockPdfFile);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.unlockPDFForms(file);
|
ResponseEntity<Resource> response = controller.unlockPDFForms(file);
|
||||||
|
|
||||||
// Controller catches exceptions and returns null
|
// Controller catches exceptions and returns null
|
||||||
assertNull(response);
|
assertNull(response);
|
||||||
@@ -114,7 +114,7 @@ class UnlockPDFFormsControllerTest {
|
|||||||
PDFFile file = new PDFFile();
|
PDFFile file = new PDFFile();
|
||||||
file.setFileInput(mockPdfFile);
|
file.setFileInput(mockPdfFile);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.unlockPDFForms(file);
|
ResponseEntity<Resource> response = controller.unlockPDFForms(file);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
String contentDisposition = response.getHeaders().getFirst("Content-Disposition");
|
String contentDisposition = response.getHeaders().getFirst("Content-Disposition");
|
||||||
@@ -133,7 +133,7 @@ class UnlockPDFFormsControllerTest {
|
|||||||
PDFFile file = new PDFFile();
|
PDFFile file = new PDFFile();
|
||||||
file.setFileInput(mockPdfFile);
|
file.setFileInput(mockPdfFile);
|
||||||
|
|
||||||
ResponseEntity<StreamingResponseBody> response = controller.unlockPDFForms(file);
|
ResponseEntity<Resource> response = controller.unlockPDFForms(file);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertTrue(acroForm.getNeedAppearances());
|
assertTrue(acroForm.getNeedAppearances());
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user