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