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.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.image.ImageBag;
019    import com.liferay.portal.kernel.image.ImageToolUtil;
020    import com.liferay.portal.kernel.io.FileFilter;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.messaging.MessageBusUtil;
024    import com.liferay.portal.kernel.repository.model.FileEntry;
025    import com.liferay.portal.kernel.repository.model.FileVersion;
026    import com.liferay.portal.kernel.util.FileUtil;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.PrefsPropsUtil;
029    import com.liferay.portal.kernel.util.PropsKeys;
030    import com.liferay.portal.kernel.util.PropsUtil;
031    import com.liferay.portal.kernel.util.StreamUtil;
032    import com.liferay.portal.kernel.util.StringBundler;
033    import com.liferay.portal.kernel.util.StringPool;
034    import com.liferay.portal.kernel.util.SystemProperties;
035    import com.liferay.portal.kernel.util.Validator;
036    import com.liferay.portal.kernel.xml.Element;
037    import com.liferay.portal.model.CompanyConstants;
038    import com.liferay.portal.util.PortalUtil;
039    import com.liferay.portal.util.PortletKeys;
040    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
041    import com.liferay.portlet.exportimport.lar.ExportImportPathUtil;
042    import com.liferay.portlet.exportimport.lar.PortletDataContext;
043    
044    import java.awt.image.RenderedImage;
045    
046    import java.io.File;
047    import java.io.InputStream;
048    
049    import java.util.List;
050    import java.util.Map;
051    import java.util.concurrent.ConcurrentHashMap;
052    import java.util.concurrent.Future;
053    
054    /**
055     * @author Alexander Chow
056     * @author Ivica Cardic
057     */
058    public abstract class DLPreviewableProcessor implements DLProcessor {
059    
060            public static final String PREVIEW_PATH = "document_preview/";
061    
062            public static final String PREVIEW_TMP_PATH =
063                    SystemProperties.get(SystemProperties.TMP_DIR) +
064                            "/liferay/" + PREVIEW_PATH;
065    
066            public static final long REPOSITORY_ID = CompanyConstants.SYSTEM;
067    
068            public static final int THUMBNAIL_INDEX_CUSTOM_1 = 1;
069    
070            public static final int THUMBNAIL_INDEX_CUSTOM_2 = 2;
071    
072            public static final int THUMBNAIL_INDEX_DEFAULT = 0;
073    
074            public static final String THUMBNAIL_PATH = "document_thumbnail/";
075    
076            public static final String THUMBNAIL_TMP_PATH =
077                    SystemProperties.get(SystemProperties.TMP_DIR) +
078                            "/liferay/" + THUMBNAIL_PATH;
079    
080            public static void deleteFiles() {
081                    long[] companyIds = PortalUtil.getCompanyIds();
082    
083                    for (long companyId : companyIds) {
084                            DLStoreUtil.deleteDirectory(companyId, REPOSITORY_ID, PREVIEW_PATH);
085                            DLStoreUtil.deleteDirectory(
086                                    companyId, REPOSITORY_ID, THUMBNAIL_PATH);
087                    }
088            }
089    
090            @Override
091            public void cleanUp(FileEntry fileEntry) {
092                    deleteFiles(fileEntry, getThumbnailType());
093            }
094    
095            @Override
096            public void cleanUp(FileVersion fileVersion) {
097                    deleteFiles(fileVersion, getThumbnailType());
098            }
099    
100            @Override
101            public void copy(
102                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
103    
104                    if (sourceFileVersion.getFileVersionId() ==
105                                    destinationFileVersion.getFileVersionId()) {
106    
107                            return;
108                    }
109    
110                    copyPreviews(sourceFileVersion, destinationFileVersion);
111                    copyThumbnails(sourceFileVersion, destinationFileVersion);
112            }
113    
114            public void deleteFiles(FileEntry fileEntry, String thumbnailType) {
115                    deleteFiles(
116                            fileEntry.getCompanyId(), fileEntry.getGroupId(),
117                            fileEntry.getFileEntryId(), -1, thumbnailType);
118            }
119    
120            public void deleteFiles(FileVersion fileVersion, String thumbnailType) {
121                    deleteFiles(
122                            fileVersion.getCompanyId(), fileVersion.getGroupId(),
123                            fileVersion.getFileEntryId(), fileVersion.getFileVersionId(),
124                            thumbnailType);
125            }
126    
127            @Override
128            public void exportGeneratedFiles(
129                            PortletDataContext portletDataContext, FileEntry fileEntry,
130                            Element fileEntryElement)
131                    throws Exception {
132    
133                    doExportGeneratedFiles(portletDataContext, fileEntry, fileEntryElement);
134            }
135    
136            @Override
137            public void importGeneratedFiles(
138                            PortletDataContext portletDataContext, FileEntry fileEntry,
139                            FileEntry importedFileEntry, Element fileEntryElement)
140                    throws Exception {
141    
142                    cleanUp(importedFileEntry.getFileVersion());
143    
144                    doImportGeneratedFiles(
145                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement);
146            }
147    
148            @Override
149            public boolean isSupported(FileVersion fileVersion) {
150                    if (fileVersion == null) {
151                            return false;
152                    }
153    
154                    if (!DLProcessorRegistryUtil.isPreviewableSize(fileVersion)) {
155                            return false;
156                    }
157    
158                    return isSupported(fileVersion.getMimeType());
159            }
160    
161            @Override
162            public void trigger(
163                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
164    
165                    if (getFileVersionIds().contains(
166                                    destinationFileVersion.getFileVersionId())) {
167    
168                            String processIdentity = Long.toString(
169                                    destinationFileVersion.getFileVersionId());
170    
171                            destroyProcess(processIdentity);
172    
173                            getFileVersionIds().remove(
174                                    destinationFileVersion.getFileVersionId());
175                    }
176            }
177    
178            protected static String getPathSegment(
179                    FileVersion fileVersion, boolean preview) {
180    
181                    return getPathSegment(
182                            fileVersion.getGroupId(), fileVersion.getFileEntryId(),
183                            fileVersion.getFileVersionId(), preview);
184            }
185    
186            protected static String getPathSegment(
187                    long groupId, long fileEntryId, long fileVersionId, boolean preview) {
188    
189                    StringBundler sb = null;
190    
191                    if (fileVersionId > 0) {
192                            sb = new StringBundler(5);
193                    }
194                    else {
195                            sb = new StringBundler(3);
196                    }
197    
198                    if (preview) {
199                            sb.append(PREVIEW_PATH);
200                    }
201                    else {
202                            sb.append(THUMBNAIL_PATH);
203                    }
204    
205                    sb.append(groupId);
206                    sb.append(DLUtil.getDividedPath(fileEntryId));
207    
208                    if (fileVersionId > 0) {
209                            sb.append(StringPool.SLASH);
210                            sb.append(fileVersionId);
211                    }
212    
213                    return sb.toString();
214            }
215    
216            protected void addFileToStore(
217                            long companyId, String dirName, String filePath, File srcFile)
218                    throws PortalException {
219    
220                    DLStoreUtil.addDirectory(companyId, REPOSITORY_ID, dirName);
221    
222                    DLStoreUtil.addFile(companyId, REPOSITORY_ID, filePath, false, srcFile);
223            }
224    
225            protected void addFileToStore(
226                            long companyId, String dirName, String filePath, InputStream is)
227                    throws PortalException {
228    
229                    DLStoreUtil.addDirectory(companyId, REPOSITORY_ID, dirName);
230    
231                    DLStoreUtil.addFile(companyId, REPOSITORY_ID, filePath, false, is);
232            }
233    
234            protected void copyPreviews(
235                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
236    
237                    try {
238                            String[] previewTypes = getPreviewTypes();
239    
240                            for (String previewType : previewTypes) {
241                                    if (hasPreview(sourceFileVersion, previewType) &&
242                                            !hasPreview(destinationFileVersion, previewType)) {
243    
244                                            String previewFilePath = getPreviewFilePath(
245                                                    destinationFileVersion, previewType);
246    
247                                            InputStream is = doGetPreviewAsStream(
248                                                    sourceFileVersion, previewType);
249    
250                                            addFileToStore(
251                                                    destinationFileVersion.getCompanyId(), PREVIEW_PATH,
252                                                    previewFilePath, is);
253                                    }
254                            }
255                    }
256                    catch (Exception e) {
257                            _log.error(e, e);
258                    }
259            }
260    
261            protected void copyThumbnail(
262                    FileVersion sourceFileVersion, FileVersion destinationFileVersion,
263                    int index) {
264    
265                    try {
266                            if (isThumbnailEnabled(index) &&
267                                    hasThumbnail(sourceFileVersion, index) &&
268                                    !hasThumbnail(destinationFileVersion, index)) {
269    
270                                    InputStream is = doGetThumbnailAsStream(
271                                            sourceFileVersion, index);
272    
273                                    String thumbnailFilePath = getThumbnailFilePath(
274                                            destinationFileVersion,
275                                            getThumbnailType(destinationFileVersion), index);
276    
277                                    addFileToStore(
278                                            destinationFileVersion.getCompanyId(), THUMBNAIL_PATH,
279                                            thumbnailFilePath, is);
280                            }
281                    }
282                    catch (Exception e) {
283                            _log.error(e, e);
284                    }
285            }
286    
287            protected void copyThumbnails(
288                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
289    
290                    copyThumbnail(
291                            sourceFileVersion, destinationFileVersion, THUMBNAIL_INDEX_DEFAULT);
292                    copyThumbnail(
293                            sourceFileVersion, destinationFileVersion,
294                            THUMBNAIL_INDEX_CUSTOM_1);
295                    copyThumbnail(
296                            sourceFileVersion, destinationFileVersion,
297                            THUMBNAIL_INDEX_CUSTOM_2);
298            }
299    
300            protected void deleteFiles(
301                    long companyId, long groupId, long fileEntryId, long fileVersionId,
302                    String thumbnailType) {
303    
304                    deletePreviews(companyId, groupId, fileEntryId, fileVersionId);
305                    deleteThumbnails(
306                            companyId, groupId, fileEntryId, fileVersionId, thumbnailType);
307            }
308    
309            protected void deletePreviews(
310                    long companyId, long groupId, long fileEntryId, long fileVersionId) {
311    
312                    String previewFilePath = getPreviewFilePath(
313                            groupId, fileEntryId, fileVersionId, null);
314    
315                    DLStoreUtil.deleteDirectory(companyId, REPOSITORY_ID, previewFilePath);
316            }
317    
318            protected void deleteThumbnail(
319                    long companyId, long groupId, long fileEntryId, long fileVersionId,
320                    String thumbnailType, int index) {
321    
322                    try {
323                            String thumbnailFilePath = getThumbnailFilePath(
324                                    groupId, fileEntryId, fileVersionId, thumbnailType, index);
325    
326                            DLStoreUtil.deleteDirectory(
327                                    companyId, REPOSITORY_ID, thumbnailFilePath);
328                    }
329                    catch (Exception e) {
330                    }
331            }
332    
333            protected void deleteThumbnails(
334                    long companyId, long groupId, long fileEntryId, long fileVersionId,
335                    String thumbnailType) {
336    
337                    deleteThumbnail(
338                            companyId, groupId, fileEntryId, fileVersionId, thumbnailType,
339                            THUMBNAIL_INDEX_DEFAULT);
340                    deleteThumbnail(
341                            companyId, groupId, fileEntryId, fileVersionId, thumbnailType,
342                            THUMBNAIL_INDEX_CUSTOM_1);
343                    deleteThumbnail(
344                            companyId, groupId, fileEntryId, fileVersionId, thumbnailType,
345                            THUMBNAIL_INDEX_CUSTOM_2);
346            }
347    
348            protected void destroyProcess(String processIdentity) {
349                    Future<?> future = futures.remove(processIdentity);
350    
351                    if (future != null) {
352                            future.cancel(true);
353    
354                            if (_log.isInfoEnabled()) {
355                                    _log.info("Cancellation requested for " + processIdentity);
356                            }
357                    }
358            }
359    
360            protected abstract void doExportGeneratedFiles(
361                            PortletDataContext portletDataContext, FileEntry fileEntry,
362                            Element fileEntryElement)
363                    throws Exception;
364    
365            protected InputStream doGetPreviewAsStream(
366                            FileVersion fileVersion, int index, String type)
367                    throws PortalException {
368    
369                    return DLStoreUtil.getFileAsStream(
370                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
371                            getPreviewFilePath(fileVersion, index, type));
372            }
373    
374            protected InputStream doGetPreviewAsStream(
375                            FileVersion fileVersion, String type)
376                    throws PortalException {
377    
378                    return doGetPreviewAsStream(fileVersion, 0, type);
379            }
380    
381            protected int doGetPreviewFileCount(FileVersion fileVersion)
382                    throws Exception {
383    
384                    try {
385                            String[] fileNames = DLStoreUtil.getFileNames(
386                                    fileVersion.getCompanyId(), REPOSITORY_ID,
387                                    getPathSegment(fileVersion, true));
388    
389                            return fileNames.length;
390                    }
391                    catch (Exception e) {
392                    }
393    
394                    return 0;
395            }
396    
397            protected long doGetPreviewFileSize(FileVersion fileVersion, int index)
398                    throws PortalException {
399    
400                    return doGetPreviewFileSize(fileVersion, index, getPreviewType());
401            }
402    
403            protected long doGetPreviewFileSize(
404                            FileVersion fileVersion, int index, String type)
405                    throws PortalException {
406    
407                    return DLStoreUtil.getFileSize(
408                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
409                            getPreviewFilePath(fileVersion, index, type));
410            }
411    
412            protected long doGetPreviewFileSize(FileVersion fileVersion, String type)
413                    throws PortalException {
414    
415                    return doGetPreviewFileSize(fileVersion, 0, type);
416            }
417    
418            protected InputStream doGetThumbnailAsStream(
419                            FileVersion fileVersion, int index)
420                    throws PortalException {
421    
422                    String type = getThumbnailType(fileVersion);
423    
424                    return DLStoreUtil.getFileAsStream(
425                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
426                            getThumbnailFilePath(fileVersion, type, index));
427            }
428    
429            protected long doGetThumbnailFileSize(FileVersion fileVersion, int index)
430                    throws PortalException {
431    
432                    String type = getThumbnailType(fileVersion);
433    
434                    return DLStoreUtil.getFileSize(
435                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
436                            getThumbnailFilePath(fileVersion, type, index));
437            }
438    
439            protected abstract void doImportGeneratedFiles(
440                            PortletDataContext portletDataContext, FileEntry fileEntry,
441                            FileEntry importedFileEntry, Element fileEntryElement)
442                    throws Exception;
443    
444            protected void exportBinary(
445                    PortletDataContext portletDataContext, Element fileEntryElement,
446                    FileVersion fileVersion, InputStream is, String binPath,
447                    String binPathName) {
448    
449                    fileEntryElement.addAttribute(binPathName, binPath);
450    
451                    if (is == null) {
452                            if (_log.isWarnEnabled()) {
453                                    _log.warn(
454                                            "No input stream found for file entry " +
455                                                    fileVersion.getFileEntryId());
456                            }
457    
458                            fileEntryElement.detach();
459    
460                            return;
461                    }
462    
463                    portletDataContext.addZipEntry(binPath, is);
464            }
465    
466            protected void exportPreview(
467                            PortletDataContext portletDataContext, FileEntry fileEntry,
468                            Element fileEntryElement, String binPathSuffix, String previewType)
469                    throws Exception {
470    
471                    exportPreview(
472                            portletDataContext, fileEntry, fileEntryElement, binPathSuffix,
473                            previewType, -1);
474            }
475    
476            protected void exportPreview(
477                            PortletDataContext portletDataContext, FileEntry fileEntry,
478                            Element fileEntryElement, String binPathSuffix, String previewType,
479                            int fileIndex)
480                    throws Exception {
481    
482                    if (portletDataContext.isPerformDirectBinaryImport()) {
483                            return;
484                    }
485    
486                    FileVersion fileVersion = fileEntry.getFileVersion();
487    
488                    if (!hasPreview(fileVersion, previewType)) {
489                            if (_log.isWarnEnabled()) {
490                                    _log.warn(
491                                            "No preview found for file entry " +
492                                                    fileEntry.getFileEntryId());
493                            }
494    
495                            return;
496                    }
497    
498                    String binPathSegment = null;
499    
500                    if (fileIndex < 0) {
501                            binPathSegment = previewType;
502                    }
503                    else {
504                            binPathSegment = Integer.toString(fileIndex + 1);
505                    }
506    
507                    String binPath = getBinPath(
508                            portletDataContext, fileEntry, binPathSegment);
509    
510                    StringBundler sb = new StringBundler(4);
511    
512                    sb.append("bin-path-preview-");
513                    sb.append(binPathSegment);
514                    sb.append("-");
515                    sb.append(binPathSuffix);
516    
517                    String binPathName = sb.toString();
518    
519                    fileEntryElement.addAttribute(binPathName, binPath);
520    
521                    InputStream is = null;
522    
523                    try {
524                            if (fileIndex < 0) {
525                                    is = doGetPreviewAsStream(fileVersion, previewType);
526                            }
527                            else {
528                                    is = doGetPreviewAsStream(
529                                            fileVersion, fileIndex + 1, previewType);
530                            }
531    
532                            exportBinary(
533                                    portletDataContext, fileEntryElement, fileVersion, is, binPath,
534                                    binPathName);
535                    }
536                    finally {
537                            StreamUtil.cleanUp(is);
538                    }
539            }
540    
541            protected void exportThumbnail(
542                            PortletDataContext portletDataContext, FileEntry fileEntry,
543                            Element fileEntryElement, String binPathName, int index)
544                    throws PortalException {
545    
546                    if (!isThumbnailEnabled(index)) {
547                            return;
548                    }
549    
550                    FileVersion fileVersion = fileEntry.getFileVersion();
551    
552                    if (!hasThumbnail(fileVersion, index)) {
553                            if (_log.isWarnEnabled()) {
554                                    _log.warn(
555                                            "No thumbnail found for file entry " +
556                                                    fileEntry.getFileEntryId());
557                            }
558    
559                            return;
560                    }
561    
562                    InputStream is = null;
563    
564                    try {
565                            is = doGetThumbnailAsStream(fileVersion, index);
566    
567                            String binPath = getBinPath(portletDataContext, fileEntry, index);
568    
569                            fileEntryElement.addAttribute(binPathName, binPath);
570    
571                            exportBinary(
572                                    portletDataContext, fileEntryElement, fileVersion, is, binPath,
573                                    binPathName);
574                    }
575                    finally {
576                            StreamUtil.cleanUp(is);
577                    }
578            }
579    
580            protected void exportThumbnails(
581                            PortletDataContext portletDataContext, FileEntry fileEntry,
582                            Element fileEntryElement, String binPathSuffix)
583                    throws PortalException {
584    
585                    FileVersion fileVersion = fileEntry.getFileVersion();
586    
587                    if (!isSupported(fileVersion)) {
588                            return;
589                    }
590    
591                    if (!portletDataContext.isPerformDirectBinaryImport()) {
592                            exportThumbnail(
593                                    portletDataContext, fileEntry, fileEntryElement,
594                                    "bin-path-thumbnail-default-" + binPathSuffix,
595                                    THUMBNAIL_INDEX_DEFAULT);
596                            exportThumbnail(
597                                    portletDataContext, fileEntry, fileEntryElement,
598                                    "bin-path-thumbnail-custom-1-" + binPathSuffix,
599                                    THUMBNAIL_INDEX_CUSTOM_1);
600                            exportThumbnail(
601                                    portletDataContext, fileEntry, fileEntryElement,
602                                    "bin-path-thumbnail-custom-2-" + binPathSuffix,
603                                    THUMBNAIL_INDEX_CUSTOM_2);
604                    }
605            }
606    
607            protected String getBinPath(
608                    PortletDataContext portletDataContext, FileEntry fileEntry, int index) {
609    
610                    StringBundler sb = new StringBundler(8);
611    
612                    sb.append(
613                            ExportImportPathUtil.getPortletPath(
614                                    portletDataContext, PortletKeys.DOCUMENT_LIBRARY));
615                    sb.append("/bin/");
616                    sb.append(fileEntry.getFileEntryId());
617                    sb.append(StringPool.SLASH);
618                    sb.append(THUMBNAIL_PATH);
619                    sb.append(fileEntry.getVersion());
620                    sb.append(StringPool.SLASH);
621                    sb.append(index);
622    
623                    return sb.toString();
624            }
625    
626            protected String getBinPath(
627                    PortletDataContext portletDataContext, FileEntry fileEntry,
628                    String type) {
629    
630                    StringBundler sb = new StringBundler(8);
631    
632                    sb.append(
633                            ExportImportPathUtil.getPortletPath(
634                                    portletDataContext, PortletKeys.DOCUMENT_LIBRARY));
635                    sb.append("/bin/");
636                    sb.append(fileEntry.getFileEntryId());
637                    sb.append(StringPool.SLASH);
638                    sb.append(PREVIEW_PATH);
639                    sb.append(fileEntry.getVersion());
640                    sb.append(StringPool.SLASH);
641                    sb.append(type);
642    
643                    return sb.toString();
644            }
645    
646            protected abstract List<Long> getFileVersionIds();
647    
648            protected String getPreviewFilePath(FileVersion fileVersion) {
649                    return getPreviewFilePath(fileVersion, 0);
650            }
651    
652            protected String getPreviewFilePath(FileVersion fileVersion, int index) {
653                    return getPreviewFilePath(fileVersion, index, getPreviewType());
654            }
655    
656            protected String getPreviewFilePath(
657                    FileVersion fileVersion, int index, String type) {
658    
659                    return getPreviewFilePath(
660                            fileVersion.getGroupId(), fileVersion.getFileEntryId(),
661                            fileVersion.getFileVersionId(), index, type);
662            }
663    
664            protected String getPreviewFilePath(FileVersion fileVersion, String type) {
665                    return getPreviewFilePath(fileVersion, 0, type);
666            }
667    
668            protected String getPreviewFilePath(
669                    long groupId, long fileEntryId, long fileVersionId, int index,
670                    String type) {
671    
672                    StringBundler sb = null;
673    
674                    if (index > 0) {
675                            sb = new StringBundler(5);
676                    }
677                    else {
678                            sb = new StringBundler(3);
679                    }
680    
681                    sb.append(getPathSegment(groupId, fileEntryId, fileVersionId, true));
682    
683                    if (index > 0) {
684                            sb.append(StringPool.SLASH);
685                            sb.append(index - 1);
686                    }
687    
688                    if (Validator.isNotNull(type)) {
689                            sb.append(StringPool.PERIOD);
690                            sb.append(type);
691                    }
692    
693                    return sb.toString();
694            }
695    
696            protected String getPreviewFilePath(
697                    long groupId, long fileEntryId, long fileVersionId, String type) {
698    
699                    return getPreviewFilePath(groupId, fileEntryId, fileVersionId, 0, type);
700            }
701    
702            protected File getPreviewTempFile(String id) {
703                    return getPreviewTempFile(id, 0);
704            }
705    
706            protected File getPreviewTempFile(String id, int index) {
707                    return getPreviewTempFile(id, index, getPreviewType());
708            }
709    
710            protected File getPreviewTempFile(String id, int index, String type) {
711                    String previewTempFilePath = getPreviewTempFilePath(id, index, type);
712    
713                    return new File(previewTempFilePath);
714            }
715    
716            protected File getPreviewTempFile(String id, String type) {
717                    return getPreviewTempFile(id, 0, type);
718            }
719    
720            protected int getPreviewTempFileCount(FileVersion fileVersion) {
721                    return getPreviewTempFileCount(fileVersion, getPreviewType());
722            }
723    
724            protected int getPreviewTempFileCount(
725                    FileVersion fileVersion, String type) {
726    
727                    String tempFileId = DLUtil.getTempFileId(
728                            fileVersion.getFileEntryId(), fileVersion.getVersion());
729    
730                    StringBundler sb = new StringBundler(5);
731    
732                    sb.append(tempFileId);
733                    sb.append(StringPool.DASH);
734                    sb.append("(.*)");
735    
736                    if (Validator.isNotNull(type)) {
737                            sb.append(StringPool.PERIOD);
738                            sb.append(type);
739                    }
740    
741                    File dir = new File(PREVIEW_TMP_PATH);
742    
743                    File[] files = dir.listFiles(new FileFilter(sb.toString()));
744    
745                    if (_log.isDebugEnabled()) {
746                            for (File file : files) {
747                                    _log.debug("Preview page for " + tempFileId + " " + file);
748                            }
749                    }
750    
751                    return files.length;
752            }
753    
754            protected String getPreviewTempFilePath(String id) {
755                    return getPreviewTempFilePath(id, 0);
756            }
757    
758            protected String getPreviewTempFilePath(String id, int index) {
759                    return getPreviewTempFilePath(id, index, getPreviewType());
760            }
761    
762            protected String getPreviewTempFilePath(String id, int index, String type) {
763                    StringBundler sb = null;
764    
765                    if (index > 0) {
766                            sb = new StringBundler(6);
767                    }
768                    else {
769                            sb = new StringBundler(4);
770                    }
771    
772                    sb.append(PREVIEW_TMP_PATH);
773                    sb.append(id);
774    
775                    if (index > 0) {
776                            sb.append(StringPool.DASH);
777                            sb.append(index - 1);
778                    }
779                    else if (index == -1) {
780                            sb.append("-%d");
781                    }
782    
783                    if (Validator.isNotNull(type)) {
784                            sb.append(StringPool.PERIOD);
785                            sb.append(type);
786                    }
787    
788                    return sb.toString();
789            }
790    
791            protected String getPreviewTempFilePath(String id, String type) {
792                    return getPreviewTempFilePath(id, 0, type);
793            }
794    
795            protected String getPreviewType() {
796                    return getPreviewType(null);
797            }
798    
799            protected abstract String getPreviewType(FileVersion fileVersion);
800    
801            protected String getPreviewType(int index) {
802                    String[] previewTypes = getPreviewTypes();
803    
804                    if ((previewTypes != null) && (previewTypes.length > index)) {
805                            return previewTypes[index];
806                    }
807                    else {
808                            return getPreviewType();
809                    }
810            }
811    
812            protected String[] getPreviewTypes() {
813                    return new String[] {getPreviewType()};
814            }
815    
816            protected String getThumbnailFilePath(FileVersion fileVersion, int index) {
817                    return getThumbnailFilePath(fileVersion, getThumbnailType(), index);
818            }
819    
820            protected String getThumbnailFilePath(
821                    FileVersion fileVersion, String type, int index) {
822    
823                    return getThumbnailFilePath(
824                            fileVersion.getGroupId(), fileVersion.getFileEntryId(),
825                            fileVersion.getFileVersionId(), type, index);
826            }
827    
828            protected String getThumbnailFilePath(
829                    long groupId, long fileEntryId, long fileVersionId,
830                    String thumbnailType, int index) {
831    
832                    StringBundler sb = new StringBundler(5);
833    
834                    sb.append(getPathSegment(groupId, fileEntryId, fileVersionId, false));
835    
836                    if (index != THUMBNAIL_INDEX_DEFAULT) {
837                            sb.append(StringPool.DASH);
838                            sb.append(index);
839                    }
840    
841                    if ((fileVersionId > 0) && Validator.isNotNull(thumbnailType)) {
842                            sb.append(StringPool.PERIOD);
843                            sb.append(thumbnailType);
844                    }
845    
846                    return sb.toString();
847            }
848    
849            protected File getThumbnailTempFile(String id) {
850                    return getThumbnailTempFile(id, getThumbnailType());
851            }
852    
853            protected File getThumbnailTempFile(String id, String type) {
854                    String thumbnailTempFilePath = getThumbnailTempFilePath(id, type);
855    
856                    return new File(thumbnailTempFilePath);
857            }
858    
859            protected String getThumbnailTempFilePath(String id) {
860                    return getThumbnailTempFilePath(id, getThumbnailType());
861            }
862    
863            protected String getThumbnailTempFilePath(String id, String type) {
864                    StringBundler sb = new StringBundler(4);
865    
866                    sb.append(THUMBNAIL_TMP_PATH);
867                    sb.append(id);
868    
869                    if (Validator.isNotNull(type)) {
870                            sb.append(StringPool.PERIOD);
871                            sb.append(type);
872                    }
873    
874                    return sb.toString();
875            }
876    
877            protected String getThumbnailType() {
878                    return getThumbnailType(null);
879            }
880    
881            protected abstract String getThumbnailType(FileVersion fileVersion);
882    
883            protected boolean hasPreview(FileVersion fileVersion, String type)
884                    throws Exception {
885    
886                    String previewFilePath = getPreviewFilePath(fileVersion, type);
887    
888                    if (DLStoreUtil.hasFile(
889                                    fileVersion.getCompanyId(), REPOSITORY_ID, previewFilePath)) {
890    
891                            return true;
892                    }
893                    else {
894                            return false;
895                    }
896            }
897    
898            protected boolean hasPreviews(FileVersion fileVersion) throws Exception {
899                    int count = 0;
900    
901                    String[] previewTypes = getPreviewTypes();
902    
903                    for (String previewType : previewTypes) {
904                            if (hasPreview(fileVersion, previewType)) {
905                                    count++;
906                            }
907                    }
908    
909                    if (count == previewTypes.length) {
910                            return true;
911                    }
912                    else {
913                            return false;
914                    }
915            }
916    
917            protected boolean hasThumbnail(FileVersion fileVersion, int index) {
918                    try {
919                            String imageType = getThumbnailType(fileVersion);
920    
921                            return DLStoreUtil.hasFile(
922                                    fileVersion.getCompanyId(), REPOSITORY_ID,
923                                    getThumbnailFilePath(fileVersion, imageType, index));
924                    }
925                    catch (Exception e) {
926                            _log.error(e, e);
927                    }
928    
929                    return false;
930            }
931    
932            protected boolean hasThumbnails(FileVersion fileVersion) {
933                    if ((isThumbnailEnabled(THUMBNAIL_INDEX_DEFAULT) &&
934                             !hasThumbnail(fileVersion, THUMBNAIL_INDEX_DEFAULT)) ||
935                            (isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_1) &&
936                             !hasThumbnail(fileVersion, THUMBNAIL_INDEX_CUSTOM_1)) ||
937                            (isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_2) &&
938                             !hasThumbnail(fileVersion, THUMBNAIL_INDEX_CUSTOM_2))) {
939    
940                            return false;
941                    }
942    
943                    return true;
944            }
945    
946            protected void importPreview(
947                            PortletDataContext portletDataContext, FileEntry fileEntry,
948                            FileEntry importedFileEntry, Element fileEntryElement,
949                            String binPathSuffix, String previewType)
950                    throws Exception {
951    
952                    importPreview(
953                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
954                            binPathSuffix, previewType, -1);
955            }
956    
957            protected void importPreview(
958                            PortletDataContext portletDataContext, FileEntry fileEntry,
959                            FileEntry importedFileEntry, Element fileEntryElement,
960                            String binPathSuffix, String previewType, int fileIndex)
961                    throws Exception {
962    
963                    if (!portletDataContext.isPerformDirectBinaryImport()) {
964                            importPreviewFromLAR(
965                                    portletDataContext, importedFileEntry, fileEntryElement,
966                                    binPathSuffix, previewType, fileIndex);
967                    }
968                    else {
969                            FileVersion importedFileVersion =
970                                    importedFileEntry.getFileVersion();
971    
972                            String previewFilePath = getPreviewFilePath(
973                                    importedFileVersion, previewType);
974    
975                            FileVersion fileVersion = fileEntry.getFileVersion();
976    
977                            if (!hasPreview(fileVersion, previewType)) {
978                                    return;
979                            }
980    
981                            InputStream is = null;
982    
983                            try {
984                                    if (fileIndex < 0) {
985                                            is = doGetPreviewAsStream(fileVersion, previewType);
986                                    }
987                                    else {
988                                            is = doGetPreviewAsStream(
989                                                    fileVersion, fileIndex, previewType);
990                                    }
991    
992                                    addFileToStore(
993                                            portletDataContext.getCompanyId(), PREVIEW_PATH,
994                                            previewFilePath, is);
995                            }
996                            finally {
997                                    StreamUtil.cleanUp(is);
998                            }
999                    }
1000            }
1001    
1002            protected void importPreviewFromLAR(
1003                            PortletDataContext portletDataContext, FileEntry fileEntry,
1004                            Element fileEntryElement, String binPathSuffix, String previewType,
1005                            int fileIndex)
1006                    throws Exception {
1007    
1008                    FileVersion fileVersion = fileEntry.getFileVersion();
1009    
1010                    String binPathSegment = null;
1011    
1012                    if (fileIndex < 0) {
1013                            binPathSegment = previewType;
1014                    }
1015                    else {
1016                            binPathSegment = Integer.toString(fileIndex + 1);
1017                    }
1018    
1019                    StringBundler sb = new StringBundler(4);
1020    
1021                    sb.append("bin-path-preview-");
1022                    sb.append(binPathSegment);
1023                    sb.append("-");
1024                    sb.append(binPathSuffix);
1025    
1026                    String binPathName = sb.toString();
1027    
1028                    String binPath = fileEntryElement.attributeValue(binPathName);
1029    
1030                    InputStream is = null;
1031    
1032                    try {
1033                            is = portletDataContext.getZipEntryAsInputStream(binPath);
1034    
1035                            if (is == null) {
1036                                    return;
1037                            }
1038    
1039                            String previewFilePath = null;
1040    
1041                            if (fileIndex < 0) {
1042                                    previewFilePath = getPreviewFilePath(fileVersion, previewType);
1043                            }
1044                            else {
1045                                    previewFilePath = getPreviewFilePath(
1046                                            fileVersion, fileIndex + 1);
1047                            }
1048    
1049                            addFileToStore(
1050                                    portletDataContext.getCompanyId(), PREVIEW_PATH,
1051                                    previewFilePath, is);
1052                    }
1053                    finally {
1054                            StreamUtil.cleanUp(is);
1055                    }
1056            }
1057    
1058            protected void importThumbnail(
1059                            PortletDataContext portletDataContext, FileEntry fileEntry,
1060                            FileEntry importedFileEntry, Element fileEntryElement,
1061                            String binPathName, int index)
1062                    throws Exception {
1063    
1064                    if (!isThumbnailEnabled(index)) {
1065                            return;
1066                    }
1067    
1068                    if (!portletDataContext.isPerformDirectBinaryImport()) {
1069                            importThumbnailFromLAR(
1070                                    portletDataContext, importedFileEntry, fileEntryElement,
1071                                    binPathName, index);
1072                    }
1073                    else {
1074                            FileVersion fileVersion = fileEntry.getFileVersion();
1075    
1076                            if (!hasThumbnail(fileVersion, index)) {
1077                                    return;
1078                            }
1079    
1080                            InputStream is = null;
1081    
1082                            try {
1083                                    is = doGetThumbnailAsStream(fileVersion, index);
1084    
1085                                    FileVersion importedFileVersion =
1086                                            importedFileEntry.getFileVersion();
1087    
1088                                    String thumbnailFilePath = getThumbnailFilePath(
1089                                            importedFileVersion, getThumbnailType(importedFileVersion),
1090                                            index);
1091    
1092                                    addFileToStore(
1093                                            portletDataContext.getCompanyId(), THUMBNAIL_PATH,
1094                                            thumbnailFilePath, is);
1095                            }
1096                            finally {
1097                                    StreamUtil.cleanUp(is);
1098                            }
1099                    }
1100            }
1101    
1102            protected void importThumbnailFromLAR(
1103                            PortletDataContext portletDataContext, FileEntry fileEntry,
1104                            Element fileEntryElement, String binPathName, int index)
1105                    throws Exception {
1106    
1107                    FileVersion fileVersion = fileEntry.getFileVersion();
1108    
1109                    String binPath = fileEntryElement.attributeValue(binPathName);
1110    
1111                    InputStream is = null;
1112    
1113                    try {
1114                            is = portletDataContext.getZipEntryAsInputStream(binPath);
1115    
1116                            if (is == null) {
1117                                    return;
1118                            }
1119    
1120                            String thumbnailFilePath = getThumbnailFilePath(
1121                                    fileVersion, getThumbnailType(fileVersion), index);
1122    
1123                            addFileToStore(
1124                                    portletDataContext.getCompanyId(), THUMBNAIL_PATH,
1125                                    thumbnailFilePath, is);
1126                    }
1127                    finally {
1128                            StreamUtil.cleanUp(is);
1129                    }
1130            }
1131    
1132            protected void importThumbnails(
1133                            PortletDataContext portletDataContext, FileEntry fileEntry,
1134                            FileEntry importedFileEntry, Element fileEntryElement,
1135                            String binPathSuffix)
1136                    throws Exception {
1137    
1138                    importThumbnail(
1139                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1140                            "bin-path-thumbnail-default-" + binPathSuffix,
1141                            THUMBNAIL_INDEX_DEFAULT);
1142                    importThumbnail(
1143                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1144                            "bin-path-thumbnail-custom-1-" + binPathSuffix,
1145                            THUMBNAIL_INDEX_CUSTOM_1);
1146                    importThumbnail(
1147                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1148                            "bin-path-thumbnail-custom-2-" + binPathSuffix,
1149                            THUMBNAIL_INDEX_CUSTOM_2);
1150            }
1151    
1152            protected boolean isThumbnailEnabled(int index) {
1153                    if ((index == THUMBNAIL_INDEX_DEFAULT) &&
1154                            GetterUtil.getBoolean(
1155                                    PropsUtil.get(PropsKeys.DL_FILE_ENTRY_THUMBNAIL_ENABLED))) {
1156    
1157                            return true;
1158                    }
1159                    else if ((index == THUMBNAIL_INDEX_CUSTOM_1) &&
1160                                     ((PrefsPropsUtil.getInteger(
1161                                             PropsKeys.
1162                                                     DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT) > 0) ||
1163                                      (PrefsPropsUtil.getInteger(
1164                                              PropsKeys.
1165                                                      DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH) > 0))) {
1166    
1167                            return true;
1168                    }
1169                    else if ((index == THUMBNAIL_INDEX_CUSTOM_2) &&
1170                                     ((PrefsPropsUtil.getInteger(
1171                                             PropsKeys.
1172                                                     DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT) > 0) ||
1173                                      (PrefsPropsUtil.getInteger(
1174                                              PropsKeys.
1175                                                      DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH) > 0))) {
1176    
1177                            return true;
1178                    }
1179    
1180                    return false;
1181            }
1182    
1183            protected void sendGenerationMessage(
1184                    String destinationName, FileVersion sourceFileVersion,
1185                    FileVersion destinationFileVersion) {
1186    
1187                    Object[] payload = {sourceFileVersion, destinationFileVersion};
1188    
1189                    MessageBusUtil.sendMessage(destinationName, payload);
1190            }
1191    
1192            protected void storeThumbnailImage(
1193                            FileVersion fileVersion, RenderedImage renderedImage, int index)
1194                    throws Exception {
1195    
1196                    if (!isThumbnailEnabled(index) || hasThumbnail(fileVersion, index)) {
1197                            return;
1198                    }
1199    
1200                    String type = getThumbnailType(fileVersion);
1201    
1202                    String maxHeightPropsKey = PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT;
1203                    String maxWidthPropsKey = PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH;
1204    
1205                    if (index == THUMBNAIL_INDEX_CUSTOM_1) {
1206                            maxHeightPropsKey =
1207                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT;
1208                            maxWidthPropsKey =
1209                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH;
1210                    }
1211                    else if (index == THUMBNAIL_INDEX_CUSTOM_2) {
1212                            maxHeightPropsKey =
1213                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT;
1214                            maxWidthPropsKey =
1215                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH;
1216                    }
1217    
1218                    RenderedImage thumbnailRenderedImage = ImageToolUtil.scale(
1219                            renderedImage, PrefsPropsUtil.getInteger(maxHeightPropsKey),
1220                            PrefsPropsUtil.getInteger(maxWidthPropsKey));
1221    
1222                    byte[] bytes = ImageToolUtil.getBytes(thumbnailRenderedImage, type);
1223    
1224                    File file = null;
1225    
1226                    try {
1227                            file = FileUtil.createTempFile(bytes);
1228    
1229                            addFileToStore(
1230                                    fileVersion.getCompanyId(), THUMBNAIL_PATH,
1231                                    getThumbnailFilePath(fileVersion, type, index), file);
1232                    }
1233                    finally {
1234                            FileUtil.delete(file);
1235                    }
1236            }
1237    
1238            protected void storeThumbnailImages(FileVersion fileVersion, File file)
1239                    throws Exception {
1240    
1241                    ImageBag imageBag = ImageToolUtil.read(file);
1242    
1243                    RenderedImage renderedImage = imageBag.getRenderedImage();
1244    
1245                    storeThumbnailImages(fileVersion, renderedImage);
1246            }
1247    
1248            protected void storeThumbnailImages(
1249                            FileVersion fileVersion, RenderedImage renderedImage)
1250                    throws Exception {
1251    
1252                    storeThumbnailImage(
1253                            fileVersion, renderedImage, THUMBNAIL_INDEX_DEFAULT);
1254                    storeThumbnailImage(
1255                            fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_1);
1256                    storeThumbnailImage(
1257                            fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_2);
1258            }
1259    
1260            protected Map<String, Future<?>> futures = new ConcurrentHashMap<>();
1261    
1262            private static final Log _log = LogFactoryUtil.getLog(
1263                    DLPreviewableProcessor.class);
1264    
1265    }