All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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 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();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy