com.xlrit.gears.plugin.pdfbox.MergedPdfDocumentProcessor Maven / Gradle / Ivy
The newest version!
package com.xlrit.gears.plugin.pdfbox;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collection;
import com.xlrit.gears.base.content.Content;
import com.xlrit.gears.base.content.ContentRef;
import com.xlrit.gears.base.content.ContentStore;
import com.xlrit.gears.base.exception.NotFoundException;
import com.xlrit.gears.base.model.Document;
import com.xlrit.gears.engine.document.DocumentProcessor;
import com.xlrit.gears.engine.meta.*;
import lombok.RequiredArgsConstructor;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(200)
@RequiredArgsConstructor
public class MergedPdfDocumentProcessor implements DocumentProcessor {
private static final Logger LOG = LoggerFactory.getLogger(MergedPdfDocumentProcessor.class);
private final ContentStore contentStore;
private final MetaManager metaManager;
@Override
public boolean supports(Document doc) {
return "merged-pdf".equals(doc.getType());
}
@Override
public ContentRef process(Document doc) {
Object parameters = doc.getParameters();
Collection contentRefs = extractContentRefsFromParameters(parameters);
byte[] data = mergeAll(contentRefs, doc.getFilename());
ContentRef contentRef = contentStore.putContent(doc.getFilename(), "application/pdf", data);
LOG.debug("Stored {} bytes as {}", data.length, contentRef);
return contentRef;
}
private Collection extractContentRefsFromParameters(Object parameters) {
ObjectInfo, BaseField> objectInfo = metaManager.getObjectInfo(parameters);
if (objectInfo.getFields().stream().noneMatch(f -> "files".equals(f.getName()))) {
throw new IllegalArgumentException("No 'files' attribute found in document parameters");
}
BaseField files = objectInfo.getField("files");
if (!(files.getTypeInfo() instanceof MultipleInfo multipleInfo)) {
throw new IllegalArgumentException("Parameter 'files' is not a multiple");
}
if (!multipleInfo.getElementType().equals(BasicTypes.FILE)) {
throw new IllegalArgumentException("Parameter 'files' element type is not file");
}
//noinspection unchecked
return (Collection) files.getValue(parameters);
}
private byte[] mergeAll(Collection contentRefs, String destFilename) {
ByteArrayOutputStream dest = new ByteArrayOutputStream();
try {
LOG.info("mergeAll: destFilename={}, contentRefs={}", destFilename, contentRefs);
if (contentRefs.isEmpty()) throw new RuntimeException("No source files to merge into " + destFilename);
PDFMergerUtility merger = new PDFMergerUtility();
merger.setDestinationStream(dest);
for (ContentRef contentRef : contentRefs) {
RandomAccessRead source = toSource(contentRef);
LOG.debug("Adding source file {} with size {}", contentRef, source.length());
merger.addSource(source);
}
merger.mergeDocuments(null);
return dest.toByteArray();
}
catch (IOException e) {
throw new RuntimeException("Unable to merge content refs: " + contentRefs, e);
}
}
private RandomAccessRead toSource(ContentRef contentRef) {
byte[] data = getContentData(contentRef);
return new RandomAccessReadBuffer(data);
}
private byte[] getContentData(ContentRef contentRef) {
Content content = contentStore.findContent(contentRef);
if (content == null) throw new NotFoundException("content", "id", contentRef.getId());
return content.getData();
}
}