/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portlet.documentlibrary.util;
import com.liferay.document.library.kernel.document.conversion.DocumentConversionUtil;
import com.liferay.document.library.kernel.exception.NoSuchFileEntryException;
import com.liferay.document.library.kernel.model.DLProcessorConstants;
import com.liferay.document.library.kernel.store.DLStoreUtil;
import com.liferay.document.library.kernel.util.DLPreviewableProcessor;
import com.liferay.document.library.kernel.util.DLUtil;
import com.liferay.document.library.kernel.util.PDFProcessor;
import com.liferay.exportimport.kernel.lar.PortletDataContext;
import com.liferay.portal.fabric.InputResource;
import com.liferay.portal.fabric.OutputResource;
import com.liferay.portal.kernel.image.GhostscriptUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.process.ClassPathUtil;
import com.liferay.portal.kernel.process.ProcessCallable;
import com.liferay.portal.kernel.process.ProcessChannel;
import com.liferay.portal.kernel.process.ProcessException;
import com.liferay.portal.kernel.process.ProcessExecutorUtil;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.repository.model.FileVersion;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.MimeTypesUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.ServerDetector;
import com.liferay.portal.kernel.util.StreamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.SystemEnv;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.log.Log4jLogFactoryImpl;
import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
import com.liferay.portal.util.PropsUtil;
import com.liferay.portal.util.PropsValues;
import com.liferay.util.log4j.Log4JUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.lang.time.StopWatch;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
/**
* @author Alexander Chow
* @author Mika Koivisto
* @author Juan González
* @author Sergio González
* @author Ivica Cardic
*/
public class PDFProcessorImpl
extends DLPreviewableProcessor implements PDFProcessor {
@Override
public void afterPropertiesSet() throws Exception {
FileUtil.mkdirs(DECRYPT_TMP_PATH);
FileUtil.mkdirs(PREVIEW_TMP_PATH);
FileUtil.mkdirs(THUMBNAIL_TMP_PATH);
}
@Override
public void generateImages(
FileVersion sourceFileVersion, FileVersion destinationFileVersion)
throws Exception {
_generateImages(sourceFileVersion, destinationFileVersion);
}
@Override
public InputStream getPreviewAsStream(FileVersion fileVersion, int index)
throws Exception {
return doGetPreviewAsStream(fileVersion, index, PREVIEW_TYPE);
}
@Override
public int getPreviewFileCount(FileVersion fileVersion) {
try {
return doGetPreviewFileCount(fileVersion);
}
catch (Exception e) {
_log.error(e, e);
}
return 0;
}
@Override
public long getPreviewFileSize(FileVersion fileVersion, int index)
throws Exception {
return doGetPreviewFileSize(fileVersion, index);
}
@Override
public InputStream getThumbnailAsStream(FileVersion fileVersion, int index)
throws Exception {
return doGetThumbnailAsStream(fileVersion, index);
}
@Override
public long getThumbnailFileSize(FileVersion fileVersion, int index)
throws Exception {
return doGetThumbnailFileSize(fileVersion, index);
}
@Override
public String getType() {
return DLProcessorConstants.PDF_PROCESSOR;
}
@Override
public boolean hasImages(FileVersion fileVersion) {
boolean hasImages = false;
try {
hasImages = _hasImages(fileVersion);
if (!hasImages && isSupported(fileVersion)) {
_queueGeneration(null, fileVersion);
}
}
catch (Exception e) {
_log.error(e, e);
}
return hasImages;
}
@Override
public boolean isDocumentSupported(FileVersion fileVersion) {
return isSupported(fileVersion);
}
@Override
public boolean isDocumentSupported(String mimeType) {
return isSupported(mimeType);
}
@Override
public boolean isSupported(String mimeType) {
if (Validator.isNull(mimeType)) {
return false;
}
if (mimeType.equals(ContentTypes.APPLICATION_PDF) ||
mimeType.equals(ContentTypes.APPLICATION_X_PDF)) {
return true;
}
if (DocumentConversionUtil.isEnabled()) {
Set<String> extensions = MimeTypesUtil.getExtensions(mimeType);
for (String extension : extensions) {
extension = extension.substring(1);
String[] targetExtensions =
DocumentConversionUtil.getConversions(extension);
if (Arrays.binarySearch(targetExtensions, "pdf") >= 0) {
return true;
}
}
}
return false;
}
@Override
public void trigger(
FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
super.trigger(sourceFileVersion, destinationFileVersion);
_queueGeneration(sourceFileVersion, destinationFileVersion);
}
@Override
protected void copyPreviews(
FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
if (!PropsValues.DL_FILE_ENTRY_PREVIEW_ENABLED) {
return;
}
try {
if (hasPreview(sourceFileVersion) &&
!hasPreview(destinationFileVersion)) {
int count = getPreviewFileCount(sourceFileVersion);
for (int i = 0; i < count; i++) {
String previewFilePath = getPreviewFilePath(
destinationFileVersion, i + 1);
InputStream is = doGetPreviewAsStream(
sourceFileVersion, i + 1, PREVIEW_TYPE);
addFileToStore(
destinationFileVersion.getCompanyId(), PREVIEW_PATH,
previewFilePath, is);
}
}
}
catch (Exception e) {
_log.error(e, e);
}
}
@Override
protected void doExportGeneratedFiles(
PortletDataContext portletDataContext, FileEntry fileEntry,
Element fileEntryElement)
throws Exception {
exportThumbnails(
portletDataContext, fileEntry, fileEntryElement, "pdf");
exportPreviews(portletDataContext, fileEntry, fileEntryElement);
}
@Override
protected void doImportGeneratedFiles(
PortletDataContext portletDataContext, FileEntry fileEntry,
FileEntry importedFileEntry, Element fileEntryElement)
throws Exception {
importThumbnails(
portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
"pdf");
importPreviews(
portletDataContext, fileEntry, importedFileEntry, fileEntryElement);
}
protected void exportPreviews(
PortletDataContext portletDataContext, FileEntry fileEntry,
Element fileEntryElement)
throws Exception {
FileVersion fileVersion = fileEntry.getFileVersion();
if (!isSupported(fileVersion) || !_hasImages(fileVersion)) {
return;
}
if (!portletDataContext.isPerformDirectBinaryImport()) {
int previewFileCount = getPreviewFileCount(fileVersion);
fileEntryElement.addAttribute(
"bin-path-pdf-preview-count", String.valueOf(previewFileCount));
for (int i = 0; i < previewFileCount; i++) {
exportPreview(
portletDataContext, fileEntry, fileEntryElement, "pdf",
PREVIEW_TYPE, i);
}
}
}
@Override
protected List<Long> getFileVersionIds() {
return _fileVersionIds;
}
@Override
protected String getPreviewType(FileVersion fileVersion) {
return PREVIEW_TYPE;
}
@Override
protected String getThumbnailType(FileVersion fileVersion) {
return THUMBNAIL_TYPE;
}
protected boolean hasPreview(FileVersion fileVersion) throws Exception {
return hasPreview(fileVersion, null);
}
@Override
protected boolean hasPreview(FileVersion fileVersion, String type)
throws Exception {
String previewFilePath = getPreviewFilePath(fileVersion, 1);
return DLStoreUtil.hasFile(
fileVersion.getCompanyId(), REPOSITORY_ID, previewFilePath);
}
protected void importPreviews(
PortletDataContext portletDataContext, FileEntry fileEntry,
FileEntry importedFileEntry, Element fileEntryElement)
throws Exception {
int previewFileCount = GetterUtil.getInteger(
fileEntryElement.attributeValue("bin-path-pdf-preview-count"));
for (int i = 0; i < previewFileCount; i++) {
importPreview(
portletDataContext, fileEntry, importedFileEntry,
fileEntryElement, "pdf", PREVIEW_TYPE, i);
}
}
private void _addDimensions(List<String> arguments, File file)
throws Exception {
Map<String, Integer> scaledDimensions = _getScaledDimensions(file);
if ((PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH != 0) &&
(PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT != 0)) {
arguments.add(
"-dDEVICEWIDTH=" +
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH);
arguments.add(
"-dDEVICEHEIGHT=" +
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT);
}
else if ((PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH != 0) &&
(PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT == 0)) {
arguments.add(
"-dDEVICEWIDTH=" +
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH);
arguments.add("-dDEVICEHEIGHT=" + scaledDimensions.get("height"));
}
else if ((PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH == 0) &&
(PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT != 0)) {
arguments.add("-dDEVICEWIDTH=" + scaledDimensions.get("width"));
arguments.add(
"-dDEVICEHEIGHT=" +
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT);
}
}
private void _generateImages(FileVersion fileVersion, File file)
throws Exception {
if (GhostscriptUtil.isEnabled()) {
if (!_ghostscriptInitialized) {
GhostscriptUtil.reset();
_ghostscriptInitialized = true;
}
_generateImagesGS(fileVersion, file);
}
else {
_generateImagesPB(fileVersion, file);
}
}
private void _generateImages(
FileVersion sourceFileVersion, FileVersion destinationFileVersion)
throws Exception {
InputStream inputStream = null;
try {
if (sourceFileVersion != null) {
copy(sourceFileVersion, destinationFileVersion);
return;
}
if (_hasImages(destinationFileVersion)) {
return;
}
String extension = destinationFileVersion.getExtension();
if (extension.equals("pdf")) {
if (destinationFileVersion instanceof LiferayFileVersion) {
try {
LiferayFileVersion liferayFileVersion =
(LiferayFileVersion)destinationFileVersion;
File file = liferayFileVersion.getFile(false);
_generateImages(destinationFileVersion, file);
return;
}
catch (UnsupportedOperationException uoe) {
}
}
inputStream = destinationFileVersion.getContentStream(false);
_generateImages(destinationFileVersion, inputStream);
}
else if (DocumentConversionUtil.isEnabled()) {
inputStream = destinationFileVersion.getContentStream(false);
String tempFileId = DLUtil.getTempFileId(
destinationFileVersion.getFileEntryId(),
destinationFileVersion.getVersion());
if (Objects.equals(
"PWC", destinationFileVersion.getVersion()) ||
destinationFileVersion.isPending()) {
File file = new File(
DocumentConversionUtil.getFilePath(tempFileId, "pdf"));
FileUtil.delete(file);
}
File file = DocumentConversionUtil.convert(
tempFileId, inputStream, extension, "pdf");
_generateImages(destinationFileVersion, file);
}
}
catch (NoSuchFileEntryException nsfee) {
if (_log.isDebugEnabled()) {
_log.debug(nsfee, nsfee);
}
}
finally {
StreamUtil.cleanUp(inputStream);
_fileVersionIds.remove(destinationFileVersion.getFileVersionId());
}
}
private void _generateImages(
FileVersion fileVersion, InputStream inputStream)
throws Exception {
if (GhostscriptUtil.isEnabled()) {
_generateImagesGS(fileVersion, inputStream);
}
else {
_generateImagesPB(fileVersion, inputStream);
}
}
private void _generateImagesGS(FileVersion fileVersion, File file)
throws Exception {
if (_isGeneratePreview(fileVersion)) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
_generateImagesGS(fileVersion, file, false);
if (_log.isInfoEnabled()) {
int previewFileCount = getPreviewFileCount(fileVersion);
_log.info(
"Ghostscript generated " + previewFileCount +
" preview pages for " + fileVersion.getTitle() +
" in " + stopWatch.getTime() + " ms");
}
}
if (_isGenerateThumbnail(fileVersion)) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
_generateImagesGS(fileVersion, file, true);
if (_log.isInfoEnabled()) {
_log.info(
"Ghostscript generated a thumbnail for " +
fileVersion.getTitle() + " in " + stopWatch.getTime() +
" ms");
}
}
}
private void _generateImagesGS(
FileVersion fileVersion, File file, boolean thumbnail)
throws Exception {
// Generate images
String tempFileId = DLUtil.getTempFileId(
fileVersion.getFileEntryId(), fileVersion.getVersion());
List<String> arguments = new ArrayList<>();
arguments.add("-sDEVICE=png16m");
if (thumbnail) {
arguments.add(
"-sOutputFile=" + getThumbnailTempFilePath(tempFileId));
arguments.add("-dFirstPage=1");
arguments.add("-dLastPage=1");
}
else {
arguments.add(
"-sOutputFile=" + getPreviewTempFilePath(tempFileId, -1));
}
arguments.add("-dPDFFitPage");
arguments.add("-dTextAlphaBits=4");
arguments.add("-dGraphicsAlphaBits=4");
arguments.add("-r" + PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_DPI);
_addDimensions(arguments, file);
arguments.add(file.getPath());
Future<?> future = GhostscriptUtil.execute(arguments);
String processIdentity = String.valueOf(fileVersion.getFileVersionId());
long ghostscriptTimeout =
PropsValues.DL_FILE_ENTRY_PREVIEW_GENERATION_TIMEOUT_GHOSTSCRIPT;
if (_log.isDebugEnabled()) {
if (thumbnail) {
_log.debug(
"Waiting for " + ghostscriptTimeout +
" seconds to generate thumbnail for " + file.getPath());
}
else {
_log.debug(
"Waiting for " + ghostscriptTimeout +
" seconds to generate preview for " + file.getPath());
}
}
try {
future.get(ghostscriptTimeout, TimeUnit.SECONDS);
futures.put(processIdentity, future);
}
catch (TimeoutException te) {
String errorMessage =
"Timeout when generating preview for " + file.getPath();
if (thumbnail) {
errorMessage =
"Timeout when generating thumbanil for " + file.getPath();
}
if (future.cancel(true)) {
errorMessage += " resulted in a canceled timeout for " + future;
}
_log.error(errorMessage);
throw te;
}
catch (Exception e) {
_log.error(e, e);
throw e;
}
// Store images
if (thumbnail) {
File thumbnailTempFile = getThumbnailTempFile(tempFileId);
try {
storeThumbnailImages(fileVersion, thumbnailTempFile);
}
finally {
FileUtil.delete(thumbnailTempFile);
}
}
else {
int total = getPreviewTempFileCount(fileVersion);
for (int i = 0; i < total; i++) {
File previewTempFile = getPreviewTempFile(tempFileId, i + 2);
try {
addFileToStore(
fileVersion.getCompanyId(), PREVIEW_PATH,
getPreviewFilePath(fileVersion, i + 1),
previewTempFile);
}
finally {
FileUtil.delete(previewTempFile);
}
}
}
}
private void _generateImagesGS(
FileVersion fileVersion, InputStream inputStream)
throws Exception {
File file = null;
try {
file = FileUtil.createTempFile(inputStream);
_generateImagesGS(fileVersion, file);
}
finally {
FileUtil.delete(file);
}
}
private void _generateImagesPB(FileVersion fileVersion, File file)
throws Exception {
String tempFileId = DLUtil.getTempFileId(
fileVersion.getFileEntryId(), fileVersion.getVersion());
File decryptedFile = getDecryptedTempFile(tempFileId);
File thumbnailFile = getThumbnailTempFile(tempFileId);
int previewFilesCount = _getPreviewFilesCount(file, decryptedFile);
if (previewFilesCount == 0) {
_log.error(
"Unable to decrypt PDF document for file version " +
fileVersion.getFileVersionId());
return;
}
File[] previewFiles = new File[previewFilesCount];
for (int i = 0; i < previewFilesCount; i++) {
previewFiles[i] = getPreviewTempFile(tempFileId, i);
}
boolean generatePreview = _isGeneratePreview(fileVersion);
boolean generateThumbnail = _isGenerateThumbnail(fileVersion);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
if (PropsValues.DL_FILE_ENTRY_PREVIEW_FORK_PROCESS_ENABLED) {
ProcessCallable<String> processCallable =
new LiferayPDFBoxProcessCallable(
ServerDetector.getServerId(),
PropsUtil.get(PropsKeys.LIFERAY_HOME),
Log4JUtil.getCustomLogSettings(), decryptedFile,
thumbnailFile, previewFiles, getThumbnailType(fileVersion),
getPreviewType(fileVersion),
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_DPI,
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT,
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH,
generatePreview, generateThumbnail);
ProcessChannel<String> processChannel = ProcessExecutorUtil.execute(
ClassPathUtil.getPortalProcessConfig(), processCallable);
Future<String> future = processChannel.getProcessNoticeableFuture();
String processIdentity = String.valueOf(
fileVersion.getFileVersionId());
long pdfBoxTimeout =
PropsValues.DL_FILE_ENTRY_PREVIEW_GENERATION_TIMEOUT_PDFBOX;
if (_log.isDebugEnabled()) {
if (generateThumbnail && generatePreview) {
_log.debug(
"Waiting for " + pdfBoxTimeout +
" seconds to generate thumbnail and preview for " +
decryptedFile.getPath());
}
else {
if (generateThumbnail) {
_log.debug(
"Waiting for " + pdfBoxTimeout +
" seconds to generate thumbnail for " +
decryptedFile.getPath());
}
if (generatePreview) {
_log.debug(
"Waiting for " + pdfBoxTimeout +
" seconds to generate preview for " +
decryptedFile.getPath());
}
}
}
try {
future.get(pdfBoxTimeout, TimeUnit.SECONDS);
futures.put(processIdentity, future);
}
catch (TimeoutException te) {
String errorMessage = null;
if (generateThumbnail && generatePreview) {
errorMessage =
"Timeout when generating thumbnail and preview for " +
decryptedFile.getPath();
}
else {
if (generateThumbnail) {
errorMessage =
"Timeout when generating thumbnail for " +
decryptedFile.getPath();
}
if (generatePreview) {
errorMessage =
"Timeout when generating preview for " +
decryptedFile.getPath();
}
}
if (future.cancel(true)) {
errorMessage +=
" resulted in a canceled timeout for " + future;
}
_log.error(errorMessage);
throw te;
}
catch (Exception e) {
_log.error(e, e);
throw e;
}
}
else {
LiferayPDFBoxConverter liferayConverter =
new LiferayPDFBoxConverter(
decryptedFile, thumbnailFile, previewFiles,
getPreviewType(fileVersion), getThumbnailType(fileVersion),
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_DPI,
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT,
PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH,
generatePreview, generateThumbnail);
liferayConverter.generateImagesPB();
}
FileUtil.delete(decryptedFile);
if (generateThumbnail) {
try {
storeThumbnailImages(fileVersion, thumbnailFile);
}
finally {
FileUtil.delete(thumbnailFile);
}
}
if (generatePreview) {
int index = 0;
for (File previewFile : previewFiles) {
try {
addFileToStore(
fileVersion.getCompanyId(), PREVIEW_PATH,
getPreviewFilePath(fileVersion, index + 1),
previewFile);
}
finally {
FileUtil.delete(previewFile);
}
index++;
}
}
if (_log.isInfoEnabled()) {
long fileVersionId = fileVersion.getFileVersionId();
int previewFileCount = getPreviewFileCount(fileVersion);
long time = stopWatch.getTime();
if (generateThumbnail && generatePreview) {
_log.info(
"PDFBox generated a thumbnail and " + previewFileCount +
" preview pages for " + fileVersionId + " in " + time +
" ms");
}
else {
if (generateThumbnail) {
_log.info(
"PDFBox generated a thumbnail for " + fileVersionId +
" in " + time + " ms");
}
if (generatePreview) {
_log.info(
"PDFBox generated " + previewFileCount +
" preview pages for " + fileVersionId + " in " +
time + " ms");
}
}
}
}
private void _generateImagesPB(
FileVersion fileVersion, InputStream inputStream)
throws Exception {
File file = null;
try {
file = FileUtil.createTempFile(inputStream);
_generateImagesPB(fileVersion, file);
}
finally {
FileUtil.delete(file);
}
}
private int _getPreviewFilesCount(File encryptedFile, File decryptedFile) {
String[] decryptPasswords = ArrayUtil.append(
PropsValues.
DL_FILE_ENTRY_PREVIEW_GENERATION_DECRYPT_PASSWORDS_PDFBOX,
StringPool.BLANK);
for (String decryptPassword : decryptPasswords) {
try (PDDocument pdDocument =
PDDocument.load(encryptedFile, decryptPassword)) {
pdDocument.setAllSecurityToBeRemoved(true);
pdDocument.save(decryptedFile);
return pdDocument.getNumberOfPages();
}
catch (IOException ioe) {
if (!(ioe instanceof InvalidPasswordException)) {
_log.error(ioe, ioe);
}
}
}
return 0;
}
private Map<String, Integer> _getScaledDimensions(File file)
throws Exception {
try (PDDocument pdDocument = PDDocument.load(file)) {
Map<String, Integer> scaledDimensions = new HashMap<>();
PDDocumentCatalog pdDocumentCatalog =
pdDocument.getDocumentCatalog();
PDPageTree pages = pdDocumentCatalog.getPages();
PDPage pdPage = pages.get(0);
PDRectangle pdRectangle = pdPage.getMediaBox();
float width = pdRectangle.getWidth();
double widthFactor =
(double)PropsValues.
DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH / width;
float height = pdRectangle.getHeight();
int scaledHeight = (int)Math.round(widthFactor * height);
scaledDimensions.put("height", scaledHeight);
double heightFactor =
(double)PropsValues.
DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT / height;
int scaledWidth = (int)Math.round(heightFactor * width);
scaledDimensions.put("width", scaledWidth);
return scaledDimensions;
}
}
private boolean _hasImages(FileVersion fileVersion) throws Exception {
if (PropsValues.DL_FILE_ENTRY_PREVIEW_ENABLED) {
if (!hasPreview(fileVersion)) {
return false;
}
}
return hasThumbnails(fileVersion);
}
private boolean _isGeneratePreview(FileVersion fileVersion)
throws Exception {
if (PropsValues.DL_FILE_ENTRY_PREVIEW_ENABLED &&
!hasPreview(fileVersion)) {
return true;
}
else {
return false;
}
}
private boolean _isGenerateThumbnail(FileVersion fileVersion)
throws Exception {
if (PropsValues.DL_FILE_ENTRY_THUMBNAIL_ENABLED &&
!hasThumbnail(fileVersion, THUMBNAIL_INDEX_DEFAULT)) {
return true;
}
else {
return false;
}
}
private void _queueGeneration(
FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
if (_fileVersionIds.contains(
destinationFileVersion.getFileVersionId())) {
return;
}
boolean generateImages = false;
String extension = destinationFileVersion.getExtension();
if (extension.equals("pdf")) {
generateImages = true;
}
else if (DocumentConversionUtil.isEnabled()) {
String[] conversions = DocumentConversionUtil.getConversions(
extension);
for (String conversion : conversions) {
if (conversion.equals("pdf")) {
generateImages = true;
break;
}
}
}
if (generateImages) {
_fileVersionIds.add(destinationFileVersion.getFileVersionId());
sendGenerationMessage(
DestinationNames.DOCUMENT_LIBRARY_PDF_PROCESSOR,
sourceFileVersion, destinationFileVersion);
}
}
private static final Log _log = LogFactoryUtil.getLog(
PDFProcessorImpl.class);
private final List<Long> _fileVersionIds = new Vector<>();
private boolean _ghostscriptInitialized;
private static class LiferayPDFBoxProcessCallable
implements ProcessCallable<String> {
public LiferayPDFBoxProcessCallable(
String serverId, String liferayHome,
Map<String, String> customLogSettings, File inputFile,
File thumbnailFile, File[] previewFiles, String extension,
String thumbnailExtension, int dpi, int height, int width,
boolean generatePreview, boolean generateThumbnail) {
_serverId = serverId;
_liferayHome = liferayHome;
_customLogSettings = customLogSettings;
_inputFile = inputFile;
_thumbnailFile = thumbnailFile;
_previewFiles = previewFiles;
_extension = extension;
_thumbnailExtension = thumbnailExtension;
_dpi = dpi;
_height = height;
_width = width;
_generatePreview = generatePreview;
_generateThumbnail = generateThumbnail;
}
@Override
public String call() throws ProcessException {
Properties systemProperties = System.getProperties();
SystemEnv.setProperties(systemProperties);
Class<?> clazz = getClass();
ClassLoader classLoader = clazz.getClassLoader();
Log4JUtil.initLog4J(
_serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
_customLogSettings);
try {
LiferayPDFBoxConverter liferayConverter =
new LiferayPDFBoxConverter(
_inputFile, _thumbnailFile, _previewFiles, _extension,
_thumbnailExtension, _dpi, _height, _width,
_generatePreview, _generateThumbnail);
liferayConverter.generateImagesPB();
}
catch (Exception e) {
throw new ProcessException(e);
}
return StringPool.BLANK;
}
private static final long serialVersionUID = 1L;
private final Map<String, String> _customLogSettings;
private final int _dpi;
private final String _extension;
private final boolean _generatePreview;
private final boolean _generateThumbnail;
private final int _height;
@InputResource
private final File _inputFile;
private final String _liferayHome;
@OutputResource
private final File[] _previewFiles;
private final String _serverId;
private final String _thumbnailExtension;
@OutputResource
private final File _thumbnailFile;
private final int _width;
}
}