001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.util;
016    
017    import com.liferay.document.library.kernel.exception.NoSuchFileEntryException;
018    import com.liferay.document.library.kernel.model.DLProcessorConstants;
019    import com.liferay.document.library.kernel.store.DLStoreUtil;
020    import com.liferay.document.library.kernel.util.DLPreviewableProcessor;
021    import com.liferay.document.library.kernel.util.DLUtil;
022    import com.liferay.document.library.kernel.util.PDFProcessor;
023    import com.liferay.exportimport.kernel.lar.PortletDataContext;
024    import com.liferay.portal.fabric.InputResource;
025    import com.liferay.portal.fabric.OutputResource;
026    import com.liferay.portal.kernel.image.GhostscriptUtil;
027    import com.liferay.portal.kernel.log.Log;
028    import com.liferay.portal.kernel.log.LogFactoryUtil;
029    import com.liferay.portal.kernel.messaging.DestinationNames;
030    import com.liferay.portal.kernel.process.ClassPathUtil;
031    import com.liferay.portal.kernel.process.ProcessCallable;
032    import com.liferay.portal.kernel.process.ProcessChannel;
033    import com.liferay.portal.kernel.process.ProcessException;
034    import com.liferay.portal.kernel.process.ProcessExecutorUtil;
035    import com.liferay.portal.kernel.repository.model.FileEntry;
036    import com.liferay.portal.kernel.repository.model.FileVersion;
037    import com.liferay.portal.kernel.util.ContentTypes;
038    import com.liferay.portal.kernel.util.FileUtil;
039    import com.liferay.portal.kernel.util.GetterUtil;
040    import com.liferay.portal.kernel.util.MimeTypesUtil;
041    import com.liferay.portal.kernel.util.PropsKeys;
042    import com.liferay.portal.kernel.util.ServerDetector;
043    import com.liferay.portal.kernel.util.StreamUtil;
044    import com.liferay.portal.kernel.util.StringPool;
045    import com.liferay.portal.kernel.util.SystemEnv;
046    import com.liferay.portal.kernel.util.Validator;
047    import com.liferay.portal.kernel.xml.Element;
048    import com.liferay.portal.log.Log4jLogFactoryImpl;
049    import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
050    import com.liferay.portal.util.PropsUtil;
051    import com.liferay.portal.util.PropsValues;
052    import com.liferay.util.log4j.Log4JUtil;
053    
054    import java.io.File;
055    import java.io.InputStream;
056    
057    import java.util.ArrayList;
058    import java.util.Arrays;
059    import java.util.List;
060    import java.util.Map;
061    import java.util.Properties;
062    import java.util.Set;
063    import java.util.Vector;
064    import java.util.concurrent.Future;
065    
066    import org.apache.commons.lang.time.StopWatch;
067    import org.apache.pdfbox.pdmodel.PDDocument;
068    
069    /**
070     * @author Alexander Chow
071     * @author Mika Koivisto
072     * @author Juan González
073     * @author Sergio González
074     * @author Ivica Cardic
075     */
076    public class PDFProcessorImpl
077            extends DLPreviewableProcessor implements PDFProcessor {
078    
079            @Override
080            public void afterPropertiesSet() throws Exception {
081                    FileUtil.mkdirs(PREVIEW_TMP_PATH);
082                    FileUtil.mkdirs(THUMBNAIL_TMP_PATH);
083            }
084    
085            @Override
086            public void generateImages(
087                            FileVersion sourceFileVersion, FileVersion destinationFileVersion)
088                    throws Exception {
089    
090                    _generateImages(sourceFileVersion, destinationFileVersion);
091            }
092    
093            @Override
094            public InputStream getPreviewAsStream(FileVersion fileVersion, int index)
095                    throws Exception {
096    
097                    return doGetPreviewAsStream(fileVersion, index, PREVIEW_TYPE);
098            }
099    
100            @Override
101            public int getPreviewFileCount(FileVersion fileVersion) {
102                    try {
103                            return doGetPreviewFileCount(fileVersion);
104                    }
105                    catch (Exception e) {
106                            _log.error(e, e);
107                    }
108    
109                    return 0;
110            }
111    
112            @Override
113            public long getPreviewFileSize(FileVersion fileVersion, int index)
114                    throws Exception {
115    
116                    return doGetPreviewFileSize(fileVersion, index);
117            }
118    
119            @Override
120            public InputStream getThumbnailAsStream(FileVersion fileVersion, int index)
121                    throws Exception {
122    
123                    return doGetThumbnailAsStream(fileVersion, index);
124            }
125    
126            @Override
127            public long getThumbnailFileSize(FileVersion fileVersion, int index)
128                    throws Exception {
129    
130                    return doGetThumbnailFileSize(fileVersion, index);
131            }
132    
133            @Override
134            public String getType() {
135                    return DLProcessorConstants.PDF_PROCESSOR;
136            }
137    
138            @Override
139            public boolean hasImages(FileVersion fileVersion) {
140                    boolean hasImages = false;
141    
142                    try {
143                            hasImages = _hasImages(fileVersion);
144    
145                            if (!hasImages && isSupported(fileVersion)) {
146                                    _queueGeneration(null, fileVersion);
147                            }
148                    }
149                    catch (Exception e) {
150                            _log.error(e, e);
151                    }
152    
153                    return hasImages;
154            }
155    
156            @Override
157            public boolean isDocumentSupported(FileVersion fileVersion) {
158                    return isSupported(fileVersion);
159            }
160    
161            @Override
162            public boolean isDocumentSupported(String mimeType) {
163                    return isSupported(mimeType);
164            }
165    
166            @Override
167            public boolean isSupported(String mimeType) {
168                    if (Validator.isNull(mimeType)) {
169                            return false;
170                    }
171    
172                    if (mimeType.equals(ContentTypes.APPLICATION_PDF) ||
173                            mimeType.equals(ContentTypes.APPLICATION_X_PDF)) {
174    
175                            return true;
176                    }
177    
178                    if (DocumentConversionUtil.isEnabled()) {
179                            Set<String> extensions = MimeTypesUtil.getExtensions(mimeType);
180    
181                            for (String extension : extensions) {
182                                    extension = extension.substring(1);
183    
184                                    String[] targetExtensions =
185                                            DocumentConversionUtil.getConversions(extension);
186    
187                                    if (Arrays.binarySearch(targetExtensions, "pdf") >= 0) {
188                                            return true;
189                                    }
190                            }
191                    }
192    
193                    return false;
194            }
195    
196            @Override
197            public void trigger(
198                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
199    
200                    super.trigger(sourceFileVersion, destinationFileVersion);
201    
202                    _queueGeneration(sourceFileVersion, destinationFileVersion);
203            }
204    
205            @Override
206            protected void copyPreviews(
207                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
208    
209                    if (!PropsValues.DL_FILE_ENTRY_PREVIEW_ENABLED) {
210                            return;
211                    }
212    
213                    try {
214                            if (hasPreview(sourceFileVersion) &&
215                                    !hasPreview(destinationFileVersion)) {
216    
217                                    int count = getPreviewFileCount(sourceFileVersion);
218    
219                                    for (int i = 0; i < count; i++) {
220                                            String previewFilePath = getPreviewFilePath(
221                                                    destinationFileVersion, i + 1);
222    
223                                            InputStream is = doGetPreviewAsStream(
224                                                    sourceFileVersion, i + 1, PREVIEW_TYPE);
225    
226                                            addFileToStore(
227                                                    destinationFileVersion.getCompanyId(), PREVIEW_PATH,
228                                                    previewFilePath, is);
229                                    }
230                            }
231                    }
232                    catch (Exception e) {
233                            _log.error(e, e);
234                    }
235            }
236    
237            @Override
238            protected void doExportGeneratedFiles(
239                            PortletDataContext portletDataContext, FileEntry fileEntry,
240                            Element fileEntryElement)
241                    throws Exception {
242    
243                    exportThumbnails(
244                            portletDataContext, fileEntry, fileEntryElement, "pdf");
245    
246                    exportPreviews(portletDataContext, fileEntry, fileEntryElement);
247            }
248    
249            @Override
250            protected void doImportGeneratedFiles(
251                            PortletDataContext portletDataContext, FileEntry fileEntry,
252                            FileEntry importedFileEntry, Element fileEntryElement)
253                    throws Exception {
254    
255                    importThumbnails(
256                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
257                            "pdf");
258    
259                    importPreviews(
260                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement);
261            }
262    
263            protected void exportPreviews(
264                            PortletDataContext portletDataContext, FileEntry fileEntry,
265                            Element fileEntryElement)
266                    throws Exception {
267    
268                    FileVersion fileVersion = fileEntry.getFileVersion();
269    
270                    if (!isSupported(fileVersion) || !_hasImages(fileVersion)) {
271                            return;
272                    }
273    
274                    if (!portletDataContext.isPerformDirectBinaryImport()) {
275                            int previewFileCount = getPreviewFileCount(fileVersion);
276    
277                            fileEntryElement.addAttribute(
278                                    "bin-path-pdf-preview-count", String.valueOf(previewFileCount));
279    
280                            for (int i = 0; i < previewFileCount; i++) {
281                                    exportPreview(
282                                            portletDataContext, fileEntry, fileEntryElement, "pdf",
283                                            PREVIEW_TYPE, i);
284                            }
285                    }
286            }
287    
288            @Override
289            protected List<Long> getFileVersionIds() {
290                    return _fileVersionIds;
291            }
292    
293            @Override
294            protected String getPreviewType(FileVersion fileVersion) {
295                    return PREVIEW_TYPE;
296            }
297    
298            @Override
299            protected String getThumbnailType(FileVersion fileVersion) {
300                    return THUMBNAIL_TYPE;
301            }
302    
303            protected boolean hasPreview(FileVersion fileVersion) throws Exception {
304                    return hasPreview(fileVersion, null);
305            }
306    
307            @Override
308            protected boolean hasPreview(FileVersion fileVersion, String type)
309                    throws Exception {
310    
311                    String previewFilePath = getPreviewFilePath(fileVersion, 1);
312    
313                    return DLStoreUtil.hasFile(
314                            fileVersion.getCompanyId(), REPOSITORY_ID, previewFilePath);
315            }
316    
317            protected void importPreviews(
318                            PortletDataContext portletDataContext, FileEntry fileEntry,
319                            FileEntry importedFileEntry, Element fileEntryElement)
320                    throws Exception {
321    
322                    int previewFileCount = GetterUtil.getInteger(
323                            fileEntryElement.attributeValue("bin-path-pdf-preview-count"));
324    
325                    for (int i = 0; i < previewFileCount; i++) {
326                            importPreview(
327                                    portletDataContext, fileEntry, importedFileEntry,
328                                    fileEntryElement, "pdf", PREVIEW_TYPE, i);
329                    }
330            }
331    
332            private void _generateImages(FileVersion fileVersion, File file)
333                    throws Exception {
334    
335                    if (GhostscriptUtil.isEnabled()) {
336                            if (!_ghostscriptInitialized) {
337                                    GhostscriptUtil.reset();
338    
339                                    _ghostscriptInitialized = true;
340                            }
341    
342                            _generateImagesGS(fileVersion, file);
343                    }
344                    else {
345                            _generateImagesPB(fileVersion, file);
346                    }
347            }
348    
349            private void _generateImages(
350                            FileVersion sourceFileVersion, FileVersion destinationFileVersion)
351                    throws Exception {
352    
353                    InputStream inputStream = null;
354    
355                    try {
356                            if (sourceFileVersion != null) {
357                                    copy(sourceFileVersion, destinationFileVersion);
358    
359                                    return;
360                            }
361    
362                            if (_hasImages(destinationFileVersion)) {
363                                    return;
364                            }
365    
366                            String extension = destinationFileVersion.getExtension();
367    
368                            if (extension.equals("pdf")) {
369                                    if (destinationFileVersion instanceof LiferayFileVersion) {
370                                            try {
371                                                    LiferayFileVersion liferayFileVersion =
372                                                            (LiferayFileVersion)destinationFileVersion;
373    
374                                                    File file = liferayFileVersion.getFile(false);
375    
376                                                    _generateImages(destinationFileVersion, file);
377    
378                                                    return;
379                                            }
380                                            catch (UnsupportedOperationException uoe) {
381                                            }
382                                    }
383    
384                                    inputStream = destinationFileVersion.getContentStream(false);
385    
386                                    _generateImages(destinationFileVersion, inputStream);
387                            }
388                            else if (DocumentConversionUtil.isEnabled()) {
389                                    inputStream = destinationFileVersion.getContentStream(false);
390    
391                                    String tempFileId = DLUtil.getTempFileId(
392                                            destinationFileVersion.getFileEntryId(),
393                                            destinationFileVersion.getVersion());
394    
395                                    if (Validator.equals(
396                                                    "PWC", destinationFileVersion.getVersion()) ||
397                                            destinationFileVersion.isPending()) {
398    
399                                            File file = new File(
400                                                    DocumentConversionUtil.getFilePath(tempFileId, "pdf"));
401    
402                                            FileUtil.delete(file);
403                                    }
404    
405                                    File file = DocumentConversionUtil.convert(
406                                            tempFileId, inputStream, extension, "pdf");
407    
408                                    _generateImages(destinationFileVersion, file);
409                            }
410                    }
411                    catch (NoSuchFileEntryException nsfee) {
412                            if (_log.isDebugEnabled()) {
413                                    _log.debug(nsfee, nsfee);
414                            }
415                    }
416                    finally {
417                            StreamUtil.cleanUp(inputStream);
418    
419                            _fileVersionIds.remove(destinationFileVersion.getFileVersionId());
420                    }
421            }
422    
423            private void _generateImages(
424                            FileVersion fileVersion, InputStream inputStream)
425                    throws Exception {
426    
427                    if (GhostscriptUtil.isEnabled()) {
428                            _generateImagesGS(fileVersion, inputStream);
429                    }
430                    else {
431                            _generateImagesPB(fileVersion, inputStream);
432                    }
433            }
434    
435            private void _generateImagesGS(FileVersion fileVersion, File file)
436                    throws Exception {
437    
438                    if (_isGeneratePreview(fileVersion)) {
439                            StopWatch stopWatch = new StopWatch();
440    
441                            stopWatch.start();
442    
443                            _generateImagesGS(fileVersion, file, false);
444    
445                            if (_log.isInfoEnabled()) {
446                                    int previewFileCount = getPreviewFileCount(fileVersion);
447    
448                                    _log.info(
449                                            "Ghostscript generated " + previewFileCount +
450                                                    " preview pages for " + fileVersion.getTitle() +
451                                                            " in " + stopWatch.getTime() + " ms");
452                            }
453                    }
454    
455                    if (_isGenerateThumbnail(fileVersion)) {
456                            StopWatch stopWatch = new StopWatch();
457    
458                            stopWatch.start();
459    
460                            _generateImagesGS(fileVersion, file, true);
461    
462                            if (_log.isInfoEnabled()) {
463                                    _log.info(
464                                            "Ghostscript generated a thumbnail for " +
465                                                    fileVersion.getTitle() + " in " + stopWatch.getTime() +
466                                                            " ms");
467                            }
468                    }
469            }
470    
471            private void _generateImagesGS(
472                            FileVersion fileVersion, File file, boolean thumbnail)
473                    throws Exception {
474    
475                    // Generate images
476    
477                    String tempFileId = DLUtil.getTempFileId(
478                            fileVersion.getFileEntryId(), fileVersion.getVersion());
479    
480                    List<String> arguments = new ArrayList<>();
481    
482                    arguments.add("-sDEVICE=png16m");
483    
484                    if (thumbnail) {
485                            arguments.add(
486                                    "-sOutputFile=" + getThumbnailTempFilePath(tempFileId));
487                            arguments.add("-dFirstPage=1");
488                            arguments.add("-dLastPage=1");
489                    }
490                    else {
491                            arguments.add(
492                                    "-sOutputFile=" + getPreviewTempFilePath(tempFileId, -1));
493                    }
494    
495                    arguments.add("-dPDFFitPage");
496                    arguments.add("-dTextAlphaBits=4");
497                    arguments.add("-dGraphicsAlphaBits=4");
498                    arguments.add("-r" + PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_DPI);
499    
500                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH != 0) {
501                            arguments.add(
502                                    "-dDEVICEWIDTH=" +
503                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH);
504                    }
505    
506                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT != 0) {
507                            arguments.add(
508                                    "-dDEVICEHEIGHT=" +
509                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT);
510                    }
511    
512                    arguments.add(file.getPath());
513    
514                    Future<?> future = GhostscriptUtil.execute(arguments);
515    
516                    String processIdentity = String.valueOf(fileVersion.getFileVersionId());
517    
518                    futures.put(processIdentity, future);
519    
520                    future.get();
521    
522                    // Store images
523    
524                    if (thumbnail) {
525                            File thumbnailTempFile = getThumbnailTempFile(tempFileId);
526    
527                            try {
528                                    storeThumbnailImages(fileVersion, thumbnailTempFile);
529                            }
530                            finally {
531                                    FileUtil.delete(thumbnailTempFile);
532                            }
533                    }
534                    else {
535                            int total = getPreviewTempFileCount(fileVersion);
536    
537                            for (int i = 0; i < total; i++) {
538                                    File previewTempFile = getPreviewTempFile(tempFileId, i + 2);
539    
540                                    try {
541                                            addFileToStore(
542                                                    fileVersion.getCompanyId(), PREVIEW_PATH,
543                                                    getPreviewFilePath(fileVersion, i + 1),
544                                                    previewTempFile);
545                                    }
546                                    finally {
547                                            FileUtil.delete(previewTempFile);
548                                    }
549                            }
550                    }
551            }
552    
553            private void _generateImagesGS(
554                            FileVersion fileVersion, InputStream inputStream)
555                    throws Exception {
556    
557                    File file = null;
558    
559                    try {
560                            file = FileUtil.createTempFile(inputStream);
561    
562                            _generateImagesGS(fileVersion, file);
563                    }
564                    finally {
565                            FileUtil.delete(file);
566                    }
567            }
568    
569            private void _generateImagesPB(FileVersion fileVersion, File file)
570                    throws Exception {
571    
572                    String tempFileId = DLUtil.getTempFileId(
573                            fileVersion.getFileEntryId(), fileVersion.getVersion());
574    
575                    File thumbnailFile = getThumbnailTempFile(tempFileId);
576    
577                    int previewFilesCount = 0;
578    
579                    try (PDDocument pdDocument = PDDocument.load(file)) {
580                            previewFilesCount = pdDocument.getNumberOfPages();
581                    }
582    
583                    File[] previewFiles = new File[previewFilesCount];
584    
585                    for (int i = 0; i < previewFilesCount; i++) {
586                            previewFiles[i] = getPreviewTempFile(tempFileId, i);
587                    }
588    
589                    boolean generatePreview = _isGeneratePreview(fileVersion);
590                    boolean generateThumbnail = _isGenerateThumbnail(fileVersion);
591    
592                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_FORK_PROCESS_ENABLED) {
593                            ProcessCallable<String> processCallable =
594                                    new LiferayPDFBoxProcessCallable(
595                                            ServerDetector.getServerId(),
596                                            PropsUtil.get(PropsKeys.LIFERAY_HOME),
597                                            Log4JUtil.getCustomLogSettings(), file, thumbnailFile,
598                                            previewFiles, getThumbnailType(fileVersion),
599                                            getPreviewType(fileVersion),
600                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_DPI,
601                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT,
602                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH,
603                                            generatePreview, generateThumbnail);
604    
605                            ProcessChannel<String> processChannel = ProcessExecutorUtil.execute(
606                                    ClassPathUtil.getPortalProcessConfig(), processCallable);
607    
608                            Future<String> future = processChannel.getProcessNoticeableFuture();
609    
610                            String processIdentity = String.valueOf(
611                                    fileVersion.getFileVersionId());
612    
613                            futures.put(processIdentity, future);
614    
615                            future.get();
616                    }
617                    else {
618                            LiferayPDFBoxConverter liferayConverter =
619                                    new LiferayPDFBoxConverter(
620                                            file, thumbnailFile, previewFiles,
621                                            getPreviewType(fileVersion), getThumbnailType(fileVersion),
622                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_DPI,
623                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_HEIGHT,
624                                            PropsValues.DL_FILE_ENTRY_PREVIEW_DOCUMENT_MAX_WIDTH,
625                                            generatePreview, generateThumbnail);
626    
627                            liferayConverter.generateImagesPB();
628                    }
629    
630                    if (generateThumbnail) {
631                            try {
632                                    storeThumbnailImages(fileVersion, thumbnailFile);
633                            }
634                            finally {
635                                    FileUtil.delete(thumbnailFile);
636                            }
637    
638                            if (_log.isInfoEnabled()) {
639                                    _log.info(
640                                            "PDFBox generated a thumbnail for " +
641                                                    fileVersion.getFileVersionId());
642                            }
643                    }
644    
645                    if (generatePreview) {
646                            int index = 0;
647    
648                            for (File previewFile : previewFiles) {
649                                    try {
650                                            addFileToStore(
651                                                    fileVersion.getCompanyId(), PREVIEW_PATH,
652                                                    getPreviewFilePath(fileVersion, index + 1),
653                                                    previewFile);
654                                    }
655                                    finally {
656                                            FileUtil.delete(previewFile);
657                                    }
658    
659                                    index++;
660                            }
661    
662                            if (_log.isInfoEnabled()) {
663                                    _log.info(
664                                            "PDFBox generated " +
665                                                    getPreviewFileCount(fileVersion) +
666                                                            " preview pages for " +
667                                                                    fileVersion.getFileVersionId());
668                            }
669                    }
670            }
671    
672            private void _generateImagesPB(
673                            FileVersion fileVersion, InputStream inputStream)
674                    throws Exception {
675    
676                    File file = null;
677    
678                    try {
679                            file = FileUtil.createTempFile(inputStream);
680    
681                            _generateImagesPB(fileVersion, file);
682                    }
683                    finally {
684                            FileUtil.delete(file);
685                    }
686            }
687    
688            private boolean _hasImages(FileVersion fileVersion) throws Exception {
689                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_ENABLED) {
690                            if (!hasPreview(fileVersion)) {
691                                    return false;
692                            }
693                    }
694    
695                    return hasThumbnails(fileVersion);
696            }
697    
698            private boolean _isGeneratePreview(FileVersion fileVersion)
699                    throws Exception {
700    
701                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_ENABLED &&
702                            !hasPreview(fileVersion)) {
703    
704                            return true;
705                    }
706                    else {
707                            return false;
708                    }
709            }
710    
711            private boolean _isGenerateThumbnail(FileVersion fileVersion)
712                    throws Exception {
713    
714                    if (PropsValues.DL_FILE_ENTRY_THUMBNAIL_ENABLED &&
715                            !hasThumbnail(fileVersion, THUMBNAIL_INDEX_DEFAULT)) {
716    
717                            return true;
718                    }
719                    else {
720                            return false;
721                    }
722            }
723    
724            private void _queueGeneration(
725                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
726    
727                    if (_fileVersionIds.contains(
728                                    destinationFileVersion.getFileVersionId())) {
729    
730                            return;
731                    }
732    
733                    boolean generateImages = false;
734    
735                    String extension = destinationFileVersion.getExtension();
736    
737                    if (extension.equals("pdf")) {
738                            generateImages = true;
739                    }
740                    else if (DocumentConversionUtil.isEnabled()) {
741                            String[] conversions = DocumentConversionUtil.getConversions(
742                                    extension);
743    
744                            for (String conversion : conversions) {
745                                    if (conversion.equals("pdf")) {
746                                            generateImages = true;
747    
748                                            break;
749                                    }
750                            }
751                    }
752    
753                    if (generateImages) {
754                            _fileVersionIds.add(destinationFileVersion.getFileVersionId());
755    
756                            sendGenerationMessage(
757                                    DestinationNames.DOCUMENT_LIBRARY_PDF_PROCESSOR,
758                                    sourceFileVersion, destinationFileVersion);
759                    }
760            }
761    
762            private static final Log _log = LogFactoryUtil.getLog(
763                    PDFProcessorImpl.class);
764    
765            private final List<Long> _fileVersionIds = new Vector<>();
766            private boolean _ghostscriptInitialized;
767    
768            private static class LiferayPDFBoxProcessCallable
769                    implements ProcessCallable<String> {
770    
771                    public LiferayPDFBoxProcessCallable(
772                            String serverId, String liferayHome,
773                            Map<String, String> customLogSettings, File inputFile,
774                            File thumbnailFile, File[] previewFiles, String extension,
775                            String thumbnailExtension, int dpi, int height, int width,
776                            boolean generatePreview, boolean generateThumbnail) {
777    
778                            _serverId = serverId;
779                            _liferayHome = liferayHome;
780                            _customLogSettings = customLogSettings;
781                            _inputFile = inputFile;
782                            _thumbnailFile = thumbnailFile;
783                            _previewFiles = previewFiles;
784                            _extension = extension;
785                            _thumbnailExtension = thumbnailExtension;
786                            _dpi = dpi;
787                            _height = height;
788                            _width = width;
789                            _generatePreview = generatePreview;
790                            _generateThumbnail = generateThumbnail;
791                    }
792    
793                    @Override
794                    public String call() throws ProcessException {
795                            Properties systemProperties = System.getProperties();
796    
797                            SystemEnv.setProperties(systemProperties);
798    
799                            Class<?> clazz = getClass();
800    
801                            ClassLoader classLoader = clazz.getClassLoader();
802    
803                            Log4JUtil.initLog4J(
804                                    _serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
805                                    _customLogSettings);
806    
807                            try {
808                                    LiferayPDFBoxConverter liferayConverter =
809                                            new LiferayPDFBoxConverter(
810                                                    _inputFile, _thumbnailFile, _previewFiles, _extension,
811                                                    _thumbnailExtension, _dpi, _height, _width,
812                                                    _generatePreview, _generateThumbnail);
813    
814                                    liferayConverter.generateImagesPB();
815                            }
816                            catch (Exception e) {
817                                    throw new ProcessException(e);
818                            }
819    
820                            return StringPool.BLANK;
821                    }
822    
823                    private static final long serialVersionUID = 1L;
824    
825                    private final Map<String, String> _customLogSettings;
826                    private final int _dpi;
827                    private final String _extension;
828                    private final boolean _generatePreview;
829                    private final boolean _generateThumbnail;
830                    private final int _height;
831    
832                    @InputResource
833                    private final File _inputFile;
834    
835                    private final String _liferayHome;
836    
837                    @OutputResource
838                    private final File[] _previewFiles;
839    
840                    private final String _serverId;
841                    private final String _thumbnailExtension;
842    
843                    @OutputResource
844                    private final File _thumbnailFile;
845    
846                    private final int _width;
847    
848            }
849    
850    }