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