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