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

com.adobe.platform.operation.pdfops.CombineFilesOperation Maven / Gradle / Ivy

There is a newer version: 1.3.1
Show newest version
/*
 * Copyright 2019 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it. If you have received this file from a source other than Adobe,
 * then your use, modification, or distribution of it requires the prior
 * written permission of Adobe.
 */

package com.adobe.platform.operation.pdfops;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import com.adobe.platform.operation.ExecutionContext;
import com.adobe.platform.operation.internal.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.platform.operation.Operation;
import com.adobe.platform.operation.exception.ServiceApiException;
import com.adobe.platform.operation.exception.ServiceUsageException;
import com.adobe.platform.operation.internal.ExtensionMediaTypeMapping;
import com.adobe.platform.operation.internal.FileRefImpl;
import com.adobe.platform.operation.internal.InternalExecutionContext;
import com.adobe.platform.operation.internal.cpf.dto.response.ContentAnalyzerResponse;
import com.adobe.platform.operation.internal.service.CombinePDFService;
import com.adobe.platform.operation.internal.api.FileDownloadApi;
import com.adobe.platform.operation.internal.exception.OperationException;
import com.adobe.platform.operation.internal.options.CombineOperationInput;
import com.adobe.platform.operation.internal.util.FileUtil;
import com.adobe.platform.operation.internal.util.PathUtil;
import com.adobe.platform.operation.internal.util.StringUtil;
import com.adobe.platform.operation.internal.util.ValidationUtil;
import com.adobe.platform.operation.io.FileRef;
import com.adobe.platform.operation.pdfops.options.PageRanges;

/**
 * Combines multiple PDF files into a single PDF file. Allows specifying which pages of the source files to combine.
 *
 * 

* Sample Usage: *

{@code   CombineFilesOperation combineFilesOperation = CombineFilesOperation.createNew();
 *   combineFilesOperation.addInput(FileRef.createFromLocalFile("~/Documents/combinePdfInput1.pdf",
 *                                                              CombineFilesOperation.SupportedSourceFormat.PDF.getMediaType()));
 *   combineFilesOperation.addInput(FileRef.createFromLocalFile("~/Documents/combinePdfInput2.pdf",
 *                                                              CombineFilesOperation.SupportedSourceFormat.PDF.getMediaType()));
 *   Credentials credentials = Credentials.serviceAccountCredentialsBuilder().fromFile("pdftools-api-credentials.json").build();
 *   FileRef result = combineFilesOperation.execute(ExecutionContext.create(credentials));
 *   result.saveAs("output/CombineFilesOutput.pdf");
 * }
*/ public class CombineFilesOperation implements Operation { private static final Logger LOGGER = LoggerFactory.getLogger(CombineFilesOperation.class); /** * Supported media types for this operation */ private static final Set SUPPORTED_SOURCE_MEDIA_TYPE = new HashSet<>(Arrays.asList(ExtensionMediaTypeMapping.PDF.getMediaType())); /** * Field representing the extension of the operation result */ private static final String TARGET_FILE_EXTENSION = ExtensionMediaTypeMapping.PDF.getExtension(); /** * Field to check if the operation instance was invoked more than once */ private boolean isInvoked = false; private List filesToCombine; private CombineFilesOperation() { this.filesToCombine = new ArrayList<>(); } /** * Constructs a {@code CombineFilesOperation} instance. * * @return a new {@code CombineFilesOperation} instance */ public static CombineFilesOperation createNew() { return new CombineFilesOperation(); } /** * Specifies a PDF file (media type "application/pdf") to be combined with other files. All pages of this file will be * added after the pages of any previously specified files. *

* For adding particular pages of a PDF file, use {@link #addInput(FileRef, PageRanges)}. * * @param sourceFileRef a PDF file to be combined */ public void addInput(FileRef sourceFileRef) { Objects.requireNonNull(sourceFileRef, "No input was set for operation"); PageRanges pageRanges = new PageRanges(); pageRanges.addAll(); filesToCombine.add(CombineOperationInput.createNew((FileRefImpl) sourceFileRef, pageRanges)); } /** * Specifies particular pages of a PDF file (media type "application/pdf") to be combined with other files. The pages will be added after * the pages of any previously specified files. *

* For adding all the pages of the file, consider {@link #addInput(FileRef)}. * * @param sourceFileRef a PDF file * @param pageRanges page ranges of the PDF file to be combined */ public void addInput(FileRef sourceFileRef, PageRanges pageRanges) { Objects.requireNonNull(sourceFileRef, "No input was set for operation"); Objects.requireNonNull(pageRanges, "No page options was provided for input file"); filesToCombine.add(CombineOperationInput.createNew((FileRefImpl) sourceFileRef, pageRanges)); } /** * Executes this operation synchronously using the supplied context and returns a new FileRef instance for the resulting file. *

* The resulting file may be stored in the system temporary directory (per java.io.tmpdir System property). * See {@link FileRef} for how temporary resources are cleaned up. * * @param context the context in which to execute the operation * @return the resulting PDF file * @throws ServiceApiException if an API call results in an error response * @throws IOException if there is an error in reading either the input source or the resulting file * @throws ServiceUsageException if service usage limits have been reached or credentials quota has been exhausted. */ @Override public FileRef execute(ExecutionContext context) throws ServiceApiException, IOException, ServiceUsageException { validateInvocationCount(); InternalExecutionContext internalExecutionContext = (InternalExecutionContext) context; this.validate(internalExecutionContext); try { LOGGER.info("All validations successfully done. Beginning Combine operation execution"); long startTimeMs = System.currentTimeMillis(); String location = CombinePDFService.combinePdf(internalExecutionContext, filesToCombine, this.getClass().getSimpleName()); String targetFileName = FileUtil.getRandomFileName(TARGET_FILE_EXTENSION); String temporaryDestinationPath = PathUtil.getTemporaryDestinationPath(targetFileName, TARGET_FILE_EXTENSION); FileDownloadApi.downloadAndSave(internalExecutionContext, location, temporaryDestinationPath, ContentAnalyzerResponse.class); LOGGER.info("Operation successfully completed. Stored Combined PDF at {}", temporaryDestinationPath); LOGGER.debug("Operation Success Info - Request ID: {}, Latency(ms): {}", StringUtil.getRequestIdFromLocation(location), System.currentTimeMillis() - startTimeMs); isInvoked = true; return FileRef.createFromLocalFile(temporaryDestinationPath); } catch (OperationException oe) { throw new ServiceApiException(oe.getErrorMessage(), oe.getRequestTrackingId(), oe.getStatusCode()); } } private void validateInvocationCount() { if (isInvoked) { LOGGER.error("Operation instance must only be invoked once"); throw new IllegalStateException("Operation instance must not be reused, can only be invoked once"); } } private void validate(InternalExecutionContext context) { ValidationUtil.validateExecutionContext(context); if (filesToCombine.isEmpty()) { throw new IllegalArgumentException("No input was provided for combining files"); } filesToCombine.forEach(file -> { ValidationUtil.validateFileWithPageOptions(file, SUPPORTED_SOURCE_MEDIA_TYPE); }); if (filesToCombine.stream().map(CombineOperationInput::getSourceFileRef).distinct().count() > 20) { throw new IllegalArgumentException("Only 20 unique input files can be combined in one combine operation instance"); } } /** * Supported source file formats for {@link CombineFilesOperation}. */ public enum SupportedSourceFormat implements MediaType { /** * Represents "application/pdf" media type */ PDF; /** * Returns the corresponding media type for this format, intended to be used for {@code mediaType} parameter in * {@link FileRef} methods. * * @return the corresponding media type */ public String getMediaType() { return ExtensionMediaTypeMapping.valueOf(name()).getMediaType().toLowerCase(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy