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                    for (String type : getPreviewTypes()) {
359                            String path = getPreviewFilePath(
360                                    groupId, fileEntryId, fileVersionId, type);
361    
362                            try {
363                                    DLStoreUtil.deleteFile(companyId, REPOSITORY_ID, path);
364                            }
365                            catch (Exception e) {
366                            }
367                    }
368            }
369    
370            protected void deleteThumbnails(
371                    long companyId, long groupId, long fileEntryId, long fileVersionId,
372                    String thumbnailType) {
373    
374                    try {
375                            String dirName = getPathSegment(
376                                    groupId, fileEntryId, fileVersionId, false);
377    
378                            if (fileVersionId > 0) {
379                                    dirName = dirName.concat(StringPool.PERIOD);
380                                    dirName = dirName.concat(thumbnailType);
381                            }
382    
383                            DLStoreUtil.deleteFile(companyId, REPOSITORY_ID, dirName);
384                    }
385                    catch (Exception e) {
386                    }
387            }
388    
389            protected void destroyProcess(String processIdentity) {
390                    synchronized (DLPreviewableProcessor.class) {
391                            Future<?> future = futures.get(processIdentity);
392    
393                            if (future != null) {
394                                    future.cancel(true);
395    
396                                    futures.remove(processIdentity);
397    
398                                    if (_log.isInfoEnabled()) {
399                                            _log.info("Cancellation requested for " + processIdentity);
400                                    }
401                            }
402                    }
403            }
404    
405            protected abstract void doExportGeneratedFiles(
406                            PortletDataContext portletDataContext, FileEntry fileEntry,
407                            Element fileEntryElement)
408                    throws Exception;
409    
410            protected InputStream doGetPreviewAsStream(
411                            FileVersion fileVersion, int index, String type)
412                    throws PortalException, SystemException {
413    
414                    return DLStoreUtil.getFileAsStream(
415                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
416                            getPreviewFilePath(fileVersion, index, type));
417            }
418    
419            protected InputStream doGetPreviewAsStream(
420                            FileVersion fileVersion, String type)
421                    throws PortalException, SystemException {
422    
423                    return doGetPreviewAsStream(fileVersion, 0, type);
424            }
425    
426            protected int doGetPreviewFileCount(FileVersion fileVersion)
427                    throws Exception {
428    
429                    try {
430                            String[] fileNames = DLStoreUtil.getFileNames(
431                                    fileVersion.getCompanyId(), REPOSITORY_ID,
432                                    getPathSegment(fileVersion, true));
433    
434                            return fileNames.length;
435                    }
436                    catch (Exception e) {
437                    }
438    
439                    return 0;
440            }
441    
442            protected long doGetPreviewFileSize(FileVersion fileVersion, int index)
443                    throws PortalException, SystemException {
444    
445                    return doGetPreviewFileSize(fileVersion, index, getPreviewType());
446            }
447    
448            protected long doGetPreviewFileSize(
449                            FileVersion fileVersion, int index, String type)
450                    throws PortalException, SystemException {
451    
452                    return DLStoreUtil.getFileSize(
453                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
454                            getPreviewFilePath(fileVersion, index, type));
455            }
456    
457            protected long doGetPreviewFileSize(FileVersion fileVersion, String type)
458                    throws PortalException, SystemException {
459    
460                    return doGetPreviewFileSize(fileVersion, 0, type);
461            }
462    
463            protected InputStream doGetThumbnailAsStream(
464                            FileVersion fileVersion, int index)
465                    throws PortalException, SystemException {
466    
467                    String type = getThumbnailType(fileVersion);
468    
469                    return DLStoreUtil.getFileAsStream(
470                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
471                            getThumbnailFilePath(fileVersion, type, index));
472            }
473    
474            protected long doGetThumbnailFileSize(FileVersion fileVersion, int index)
475                    throws PortalException, SystemException {
476    
477                    String type = getThumbnailType(fileVersion);
478    
479                    return DLStoreUtil.getFileSize(
480                            fileVersion.getCompanyId(), CompanyConstants.SYSTEM,
481                            getThumbnailFilePath(fileVersion, type, index));
482            }
483    
484            protected abstract void doImportGeneratedFiles(
485                            PortletDataContext portletDataContext, FileEntry fileEntry,
486                            FileEntry importedFileEntry, Element fileEntryElement)
487                    throws Exception;
488    
489            protected void exportBinary(
490                            PortletDataContext portletDataContext, Element fileEntryElement,
491                            FileVersion fileVersion, InputStream is, String binPath,
492                            String binPathName)
493                    throws SystemException {
494    
495                    fileEntryElement.addAttribute(binPathName, binPath);
496    
497                    if (is == null) {
498                            if (_log.isWarnEnabled()) {
499                                    _log.warn(
500                                            "No input stream found for file entry " +
501                                                    fileVersion.getFileEntryId());
502                            }
503    
504                            fileEntryElement.detach();
505    
506                            return;
507                    }
508    
509                    portletDataContext.addZipEntry(binPath, is);
510            }
511    
512            protected void exportPreview(
513                            PortletDataContext portletDataContext, FileEntry fileEntry,
514                            Element fileEntryElement, String binPathSuffix, String previewType)
515                    throws Exception {
516    
517                    exportPreview(
518                            portletDataContext, fileEntry, fileEntryElement, binPathSuffix,
519                            previewType, -1);
520            }
521    
522            protected void exportPreview(
523                            PortletDataContext portletDataContext, FileEntry fileEntry,
524                            Element fileEntryElement, String binPathSuffix, String previewType,
525                            int fileIndex)
526                    throws Exception {
527    
528                    if (portletDataContext.isPerformDirectBinaryImport()) {
529                            return;
530                    }
531    
532                    FileVersion fileVersion = fileEntry.getFileVersion();
533    
534                    if (!hasPreview(fileVersion, previewType)) {
535                            if (_log.isWarnEnabled()) {
536                                    _log.warn(
537                                            "No preview found for file entry " +
538                                                    fileEntry.getFileEntryId());
539                            }
540    
541                            return;
542                    }
543    
544                    String binPathSegment = null;
545    
546                    if (fileIndex < 0) {
547                            binPathSegment = previewType;
548                    }
549                    else {
550                            binPathSegment = Integer.toString(fileIndex + 1);
551                    }
552    
553                    String binPath = getBinPath(
554                            portletDataContext, fileEntry, binPathSegment);
555    
556                    StringBundler sb = new StringBundler(4);
557    
558                    sb.append("bin-path-preview-");
559                    sb.append(binPathSegment);
560                    sb.append("-");
561                    sb.append(binPathSuffix);
562    
563                    String binPathName = sb.toString();
564    
565                    fileEntryElement.addAttribute(binPathName, binPath);
566    
567                    InputStream is = null;
568    
569                    try {
570                            if (fileIndex < 0) {
571                                    is = doGetPreviewAsStream(fileVersion, previewType);
572                            }
573                            else {
574                                    is = doGetPreviewAsStream(
575                                            fileVersion, fileIndex + 1, previewType);
576                            }
577    
578                            exportBinary(
579                                    portletDataContext, fileEntryElement, fileVersion, is, binPath,
580                                    binPathName);
581                    }
582                    finally {
583                            StreamUtil.cleanUp(is);
584                    }
585            }
586    
587            protected void exportThumbnail(
588                            PortletDataContext portletDataContext, FileEntry fileEntry,
589                            Element fileEntryElement, String binPathName, int index)
590                    throws PortalException, SystemException {
591    
592                    FileVersion fileVersion = fileEntry.getFileVersion();
593    
594                    if (!hasThumbnail(fileVersion, index)) {
595                            if (_log.isWarnEnabled()) {
596                                    _log.warn(
597                                            "No thumbnail found for file entry " +
598                                                    fileEntry.getFileEntryId());
599                            }
600    
601                            return;
602                    }
603    
604                    InputStream is = null;
605    
606                    try {
607                            is = doGetThumbnailAsStream(fileVersion, index);
608    
609                            String binPath = getBinPath(portletDataContext, fileEntry, index);
610    
611                            fileEntryElement.addAttribute(binPathName, binPath);
612    
613                            exportBinary(
614                                    portletDataContext, fileEntryElement, fileVersion, is, binPath,
615                                    binPathName);
616                    }
617                    finally {
618                            StreamUtil.cleanUp(is);
619                    }
620            }
621    
622            protected void exportThumbnails(
623                            PortletDataContext portletDataContext, FileEntry fileEntry,
624                            Element fileEntryElement, String binPathSuffix)
625                    throws PortalException, SystemException {
626    
627                    FileVersion fileVersion = fileEntry.getFileVersion();
628    
629                    if (!isSupported(fileVersion) || !hasThumbnails(fileVersion)) {
630                            return;
631                    }
632    
633                    if (!portletDataContext.isPerformDirectBinaryImport()) {
634                            exportThumbnail(
635                                    portletDataContext, fileEntry, fileEntryElement,
636                                    "bin-path-thumbnail-default-" + binPathSuffix,
637                                    THUMBNAIL_INDEX_DEFAULT);
638    
639                            exportThumbnail(
640                                    portletDataContext, fileEntry, fileEntryElement,
641                                    "bin-path-thumbnail-custom-1-" + binPathSuffix,
642                                    THUMBNAIL_INDEX_CUSTOM_1);
643    
644                            exportThumbnail(
645                                    portletDataContext, fileEntry, fileEntryElement,
646                                    "bin-path-thumbnail-custom-2-" + binPathSuffix,
647                                    THUMBNAIL_INDEX_CUSTOM_2);
648                    }
649            }
650    
651            protected String getBinPath(
652                    PortletDataContext portletDataContext, FileEntry fileEntry, int index) {
653    
654                    StringBundler sb = new StringBundler(8);
655    
656                    sb.append(
657                            ExportImportPathUtil.getPortletPath(
658                                    portletDataContext, PortletKeys.DOCUMENT_LIBRARY));
659                    sb.append("/bin/");
660                    sb.append(fileEntry.getFileEntryId());
661                    sb.append(StringPool.SLASH);
662                    sb.append(THUMBNAIL_PATH);
663                    sb.append(fileEntry.getVersion());
664                    sb.append(StringPool.SLASH);
665                    sb.append(index);
666    
667                    return sb.toString();
668            }
669    
670            protected String getBinPath(
671                    PortletDataContext portletDataContext, FileEntry fileEntry,
672                    String type) {
673    
674                    StringBundler sb = new StringBundler(8);
675    
676                    sb.append(
677                            ExportImportPathUtil.getPortletPath(
678                                    portletDataContext, PortletKeys.DOCUMENT_LIBRARY));
679                    sb.append("/bin/");
680                    sb.append(fileEntry.getFileEntryId());
681                    sb.append(StringPool.SLASH);
682                    sb.append(PREVIEW_PATH);
683                    sb.append(fileEntry.getVersion());
684                    sb.append(StringPool.SLASH);
685                    sb.append(type);
686    
687                    return sb.toString();
688            }
689    
690            protected abstract List<Long> getFileVersionIds();
691    
692            protected String getPreviewFilePath(FileVersion fileVersion) {
693                    return getPreviewFilePath(fileVersion, 0);
694            }
695    
696            protected String getPreviewFilePath(FileVersion fileVersion, int index) {
697                    return getPreviewFilePath(fileVersion, index, getPreviewType());
698            }
699    
700            protected String getPreviewFilePath(
701                    FileVersion fileVersion, int index, String type) {
702    
703                    return getPreviewFilePath(
704                            fileVersion.getGroupId(), fileVersion.getFileEntryId(),
705                            fileVersion.getFileVersionId(), index, type);
706            }
707    
708            protected String getPreviewFilePath(FileVersion fileVersion, String type) {
709                    return getPreviewFilePath(fileVersion, 0, type);
710            }
711    
712            protected String getPreviewFilePath(
713                    long groupId, long fileEntryId, long fileVersionId, int index,
714                    String type) {
715    
716                    StringBundler sb = null;
717    
718                    if (index > 0) {
719                            sb = new StringBundler(5);
720                    }
721                    else {
722                            sb = new StringBundler(3);
723                    }
724    
725                    sb.append(getPathSegment(groupId, fileEntryId, fileVersionId, true));
726    
727                    if (index > 0) {
728                            sb.append(StringPool.SLASH);
729                            sb.append(index - 1);
730                    }
731    
732                    sb.append(StringPool.PERIOD);
733                    sb.append(type);
734    
735                    return sb.toString();
736            }
737    
738            protected String getPreviewFilePath(
739                    long groupId, long fileEntryId, long fileVersionId, String type) {
740    
741                    return getPreviewFilePath(groupId, fileEntryId, fileVersionId, 0, type);
742            }
743    
744            protected File getPreviewTempFile(String id) {
745                    return getPreviewTempFile(id, 0);
746            }
747    
748            protected File getPreviewTempFile(String id, int index) {
749                    return getPreviewTempFile(id, index, getPreviewType());
750            }
751    
752            protected File getPreviewTempFile(String id, int index, String type) {
753                    String previewTempFilePath = getPreviewTempFilePath(id, index, type);
754    
755                    return new File(previewTempFilePath);
756            }
757    
758            protected File getPreviewTempFile(String id, String type) {
759                    return getPreviewTempFile(id, 0, type);
760            }
761    
762            protected int getPreviewTempFileCount(FileVersion fileVersion) {
763                    return getPreviewTempFileCount(fileVersion, getPreviewType());
764            }
765    
766            protected int getPreviewTempFileCount(
767                    FileVersion fileVersion, String type) {
768    
769                    String tempFileId = DLUtil.getTempFileId(
770                            fileVersion.getFileEntryId(), fileVersion.getVersion());
771    
772                    StringBundler sb = new StringBundler(5);
773    
774                    sb.append(tempFileId);
775                    sb.append(StringPool.DASH);
776                    sb.append("(.*)");
777                    sb.append(StringPool.PERIOD);
778                    sb.append(type);
779    
780                    File dir = new File(PREVIEW_TMP_PATH);
781    
782                    File[] files = dir.listFiles(new FileFilter(sb.toString()));
783    
784                    if (_log.isDebugEnabled()) {
785                            for (File file : files) {
786                                    _log.debug("Preview page for " + tempFileId + " " + file);
787                            }
788                    }
789    
790                    return files.length;
791            }
792    
793            protected String getPreviewTempFilePath(String id) {
794                    return getPreviewTempFilePath(id, 0);
795            }
796    
797            protected String getPreviewTempFilePath(String id, int index) {
798                    return getPreviewTempFilePath(id, index, getPreviewType());
799            }
800    
801            protected String getPreviewTempFilePath(String id, int index, String type) {
802                    StringBundler sb = null;
803    
804                    if (index > 0) {
805                            sb = new StringBundler(6);
806                    }
807                    else {
808                            sb = new StringBundler(4);
809                    }
810    
811                    sb.append(PREVIEW_TMP_PATH);
812                    sb.append(id);
813    
814                    if (index > 0) {
815                            sb.append(StringPool.DASH);
816                            sb.append(index - 1);
817                    }
818                    else if (index == -1) {
819                            sb.append("-%d");
820                    }
821    
822                    sb.append(StringPool.PERIOD);
823                    sb.append(type);
824    
825                    return sb.toString();
826            }
827    
828            protected String getPreviewTempFilePath(String id, String type) {
829                    return getPreviewTempFilePath(id, 0, type);
830            }
831    
832            protected String getPreviewType() {
833                    return getPreviewType(null);
834            }
835    
836            protected abstract String getPreviewType(FileVersion fileVersion);
837    
838            protected String getPreviewType(int index) {
839                    String[] previewTypes = getPreviewTypes();
840    
841                    if ((previewTypes != null) && (previewTypes.length > index)) {
842                            return previewTypes[index];
843                    }
844                    else {
845                            return getPreviewType();
846                    }
847            }
848    
849            protected String[] getPreviewTypes() {
850                    return new String[] {getPreviewType()};
851            }
852    
853            protected String getThumbnailFilePath(FileVersion fileVersion, int index) {
854                    return getThumbnailFilePath(fileVersion, getThumbnailType(), index);
855            }
856    
857            protected String getThumbnailFilePath(
858                    FileVersion fileVersion, String type, int index) {
859    
860                    StringBundler sb = new StringBundler(5);
861    
862                    sb.append(getPathSegment(fileVersion, false));
863    
864                    if (index != THUMBNAIL_INDEX_DEFAULT) {
865                            sb.append(StringPool.DASH);
866                            sb.append(index);
867                    }
868    
869                    sb.append(StringPool.PERIOD);
870                    sb.append(type);
871    
872                    return sb.toString();
873            }
874    
875            protected File getThumbnailTempFile(String id) {
876                    return getThumbnailTempFile(id, getThumbnailType());
877            }
878    
879            protected File getThumbnailTempFile(String id, String type) {
880                    String thumbnailTempFilePath = getThumbnailTempFilePath(id, type);
881    
882                    return new File(thumbnailTempFilePath);
883            }
884    
885            protected String getThumbnailTempFilePath(String id) {
886                    return getThumbnailTempFilePath(id, getThumbnailType());
887            }
888    
889            protected String getThumbnailTempFilePath(String id, String type) {
890                    StringBundler sb = new StringBundler(4);
891    
892                    sb.append(THUMBNAIL_TMP_PATH);
893                    sb.append(id);
894                    sb.append(StringPool.PERIOD);
895                    sb.append(type);
896    
897                    return sb.toString();
898            }
899    
900            protected String getThumbnailType() {
901                    return getThumbnailType(null);
902            }
903    
904            protected abstract String getThumbnailType(FileVersion fileVersion);
905    
906            protected boolean hasPreview(FileVersion fileVersion, String type)
907                    throws Exception {
908    
909                    String previewFilePath = getPreviewFilePath(fileVersion, type);
910    
911                    if (DLStoreUtil.hasFile(
912                                    fileVersion.getCompanyId(), REPOSITORY_ID, previewFilePath)) {
913    
914                            return true;
915                    }
916                    else {
917                            return false;
918                    }
919            }
920    
921            protected boolean hasPreviews(FileVersion fileVersion) throws Exception {
922                    int count = 0;
923    
924                    String[] previewTypes = getPreviewTypes();
925    
926                    for (String previewType : previewTypes) {
927                            if (hasPreview(fileVersion, previewType)) {
928                                    count++;
929                            }
930                    }
931    
932                    if (count == previewTypes.length) {
933                            return true;
934                    }
935                    else {
936                            return false;
937                    }
938            }
939    
940            protected boolean hasThumbnail(FileVersion fileVersion, int index) {
941                    try {
942                            String imageType = getThumbnailType(fileVersion);
943    
944                            return DLStoreUtil.hasFile(
945                                    fileVersion.getCompanyId(), REPOSITORY_ID,
946                                    getThumbnailFilePath(fileVersion, imageType, index));
947                    }
948                    catch (Exception e) {
949                            _log.error(e, e);
950                    }
951    
952                    return false;
953            }
954    
955            protected boolean hasThumbnails(FileVersion fileVersion) {
956                    try {
957                            if (isThumbnailEnabled(THUMBNAIL_INDEX_DEFAULT)) {
958                                    if (!hasThumbnail(fileVersion, THUMBNAIL_INDEX_DEFAULT)) {
959                                            return false;
960                                    }
961                            }
962    
963                            if (isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_1)) {
964                                    if (!hasThumbnail(fileVersion, THUMBNAIL_INDEX_CUSTOM_1)) {
965                                            return false;
966                                    }
967                            }
968    
969                            if (isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_2)) {
970                                    if (!hasThumbnail(fileVersion, THUMBNAIL_INDEX_CUSTOM_2)) {
971                                            return false;
972                                    }
973                            }
974                    }
975                    catch (Exception e) {
976                            _log.error(e, e);
977                    }
978    
979                    return true;
980            }
981    
982            protected void importPreview(
983                            PortletDataContext portletDataContext, FileEntry fileEntry,
984                            FileEntry importedFileEntry, Element fileEntryElement,
985                            String binPathSuffix, String previewType)
986                    throws Exception {
987    
988                    importPreview(
989                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
990                            binPathSuffix, previewType, -1);
991            }
992    
993            protected void importPreview(
994                            PortletDataContext portletDataContext, FileEntry fileEntry,
995                            FileEntry importedFileEntry, Element fileEntryElement,
996                            String binPathSuffix, String previewType, int fileIndex)
997                    throws Exception {
998    
999                    if (!portletDataContext.isPerformDirectBinaryImport()) {
1000                            importPreviewFromLAR(
1001                                    portletDataContext, importedFileEntry, fileEntryElement,
1002                                    binPathSuffix, previewType, fileIndex);
1003                    }
1004                    else {
1005                            FileVersion importedFileVersion =
1006                                    importedFileEntry.getFileVersion();
1007    
1008                            String previewFilePath = getPreviewFilePath(
1009                                    importedFileVersion, previewType);
1010    
1011                            FileVersion fileVersion = fileEntry.getFileVersion();
1012    
1013                            if (!hasPreview(fileVersion, previewType)) {
1014                                    return;
1015                            }
1016    
1017                            InputStream is = null;
1018    
1019                            try {
1020                                    if (fileIndex < 0) {
1021                                            is = doGetPreviewAsStream(fileVersion, previewType);
1022                                    }
1023                                    else {
1024                                            is = doGetPreviewAsStream(
1025                                                    fileVersion, fileIndex, previewType);
1026                                    }
1027    
1028                                    addFileToStore(
1029                                            portletDataContext.getCompanyId(), PREVIEW_PATH,
1030                                            previewFilePath, is);
1031                            }
1032                            finally {
1033                                    StreamUtil.cleanUp(is);
1034                            }
1035                    }
1036            }
1037    
1038            protected void importPreviewFromLAR(
1039                            PortletDataContext portletDataContext, FileEntry fileEntry,
1040                            Element fileEntryElement, String binPathSuffix, String previewType,
1041                            int fileIndex)
1042                    throws Exception {
1043    
1044                    FileVersion fileVersion = fileEntry.getFileVersion();
1045    
1046                    String binPathSegment = null;
1047    
1048                    if (fileIndex < 0) {
1049                            binPathSegment = previewType;
1050                    }
1051                    else {
1052                            binPathSegment = Integer.toString(fileIndex + 1);
1053                    }
1054    
1055                    StringBundler sb = new StringBundler(4);
1056    
1057                    sb.append("bin-path-preview-");
1058                    sb.append(binPathSegment);
1059                    sb.append("-");
1060                    sb.append(binPathSuffix);
1061    
1062                    String binPathName = sb.toString();
1063    
1064                    String binPath = fileEntryElement.attributeValue(binPathName);
1065    
1066                    InputStream is = null;
1067    
1068                    try {
1069                            is = portletDataContext.getZipEntryAsInputStream(binPath);
1070    
1071                            if (is == null) {
1072                                    return;
1073                            }
1074    
1075                            String previewFilePath = null;
1076    
1077                            if (fileIndex < 0) {
1078                                    previewFilePath = getPreviewFilePath(fileVersion, previewType);
1079                            }
1080                            else {
1081                                    previewFilePath = getPreviewFilePath(
1082                                            fileVersion, fileIndex + 1);
1083                            }
1084    
1085                            addFileToStore(
1086                                    portletDataContext.getCompanyId(), PREVIEW_PATH,
1087                                    previewFilePath, is);
1088                    }
1089                    finally {
1090                            StreamUtil.cleanUp(is);
1091                    }
1092            }
1093    
1094            protected void importThumbnail(
1095                            PortletDataContext portletDataContext, FileEntry fileEntry,
1096                            FileEntry importedFileEntry, Element fileEntryElement,
1097                            String binPathName, int index)
1098                    throws Exception {
1099    
1100                    if (!portletDataContext.isPerformDirectBinaryImport()) {
1101                            importThumbnailFromLAR(
1102                                    portletDataContext, importedFileEntry, fileEntryElement,
1103                                    binPathName, index);
1104                    }
1105                    else {
1106                            FileVersion fileVersion = fileEntry.getFileVersion();
1107    
1108                            if (!hasThumbnail(fileVersion, index)) {
1109                                    return;
1110                            }
1111    
1112                            InputStream is = null;
1113    
1114                            try {
1115                                    is = doGetThumbnailAsStream(fileVersion, index);
1116    
1117                                    FileVersion importedFileVersion =
1118                                            importedFileEntry.getFileVersion();
1119    
1120                                    String thumbnailFilePath = getThumbnailFilePath(
1121                                            importedFileVersion, getThumbnailType(importedFileVersion),
1122                                            index);
1123    
1124                                    addFileToStore(
1125                                            portletDataContext.getCompanyId(), THUMBNAIL_PATH,
1126                                            thumbnailFilePath, is);
1127                            }
1128                            finally {
1129                                    StreamUtil.cleanUp(is);
1130                            }
1131                    }
1132            }
1133    
1134            protected void importThumbnailFromLAR(
1135                            PortletDataContext portletDataContext, FileEntry fileEntry,
1136                            Element fileEntryElement, String binPathName, int index)
1137                    throws Exception {
1138    
1139                    FileVersion fileVersion = fileEntry.getFileVersion();
1140    
1141                    String binPath = fileEntryElement.attributeValue(binPathName);
1142    
1143                    InputStream is = null;
1144    
1145                    try {
1146                            is = portletDataContext.getZipEntryAsInputStream(binPath);
1147    
1148                            if (is == null) {
1149                                    return;
1150                            }
1151    
1152                            String thumbnailFilePath = getThumbnailFilePath(
1153                                    fileVersion, getThumbnailType(fileVersion), index);
1154    
1155                            addFileToStore(
1156                                    portletDataContext.getCompanyId(), THUMBNAIL_PATH,
1157                                    thumbnailFilePath, is);
1158                    }
1159                    finally {
1160                            StreamUtil.cleanUp(is);
1161                    }
1162            }
1163    
1164            protected void importThumbnails(
1165                            PortletDataContext portletDataContext, FileEntry fileEntry,
1166                            FileEntry importedFileEntry, Element fileEntryElement,
1167                            String binPathSuffix)
1168                    throws Exception {
1169    
1170                    importThumbnail(
1171                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1172                            "bin-path-thumbnail-default-" + binPathSuffix,
1173                            THUMBNAIL_INDEX_DEFAULT);
1174    
1175                    importThumbnail(
1176                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1177                            "bin-path-thumbnail-custom-1-" + binPathSuffix,
1178                            THUMBNAIL_INDEX_CUSTOM_1);
1179    
1180                    importThumbnail(
1181                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1182                            "bin-path-thumbnail-custom-2-" + binPathSuffix,
1183                            THUMBNAIL_INDEX_CUSTOM_2);
1184            }
1185    
1186            protected boolean isThumbnailEnabled(int index) throws Exception {
1187                    if (index == THUMBNAIL_INDEX_DEFAULT) {
1188                            if (GetterUtil.getBoolean(
1189                                            PropsUtil.get(
1190                                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_ENABLED))) {
1191    
1192                                    return true;
1193                            }
1194                    }
1195                    else if (index == THUMBNAIL_INDEX_CUSTOM_1) {
1196                            if ((PrefsPropsUtil.getInteger(
1197                                            PropsKeys.
1198                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT) > 0) ||
1199                                    (PrefsPropsUtil.getInteger(
1200                                            PropsKeys.
1201                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH) > 0)) {
1202    
1203                                    return true;
1204                            }
1205                    }
1206                    else if (index == THUMBNAIL_INDEX_CUSTOM_2) {
1207                            if ((PrefsPropsUtil.getInteger(
1208                                            PropsKeys.
1209                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT) > 0) ||
1210                                    (PrefsPropsUtil.getInteger(
1211                                            PropsKeys.
1212                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH) > 0)) {
1213    
1214                                    return true;
1215                            }
1216                    }
1217    
1218                    return false;
1219            }
1220    
1221            protected void sendGenerationMessage(
1222                    String destinationName, FileVersion sourceFileVersion,
1223                    FileVersion destinationFileVersion) {
1224    
1225                    Object[] payload = {sourceFileVersion, destinationFileVersion};
1226    
1227                    MessageBusUtil.sendMessage(destinationName, payload);
1228            }
1229    
1230            protected void storeThumbnailImages(FileVersion fileVersion, File file)
1231                    throws Exception {
1232    
1233                    ImageBag imageBag = ImageToolUtil.read(file);
1234    
1235                    RenderedImage renderedImage = imageBag.getRenderedImage();
1236    
1237                    storeThumbnailImages(fileVersion, renderedImage);
1238            }
1239    
1240            protected void storeThumbnailImages(
1241                            FileVersion fileVersion, RenderedImage renderedImage)
1242                    throws Exception {
1243    
1244                    storeThumbnailmage(fileVersion, renderedImage, THUMBNAIL_INDEX_DEFAULT);
1245                    storeThumbnailmage(
1246                            fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_1);
1247                    storeThumbnailmage(
1248                            fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_2);
1249            }
1250    
1251            protected void storeThumbnailmage(
1252                            FileVersion fileVersion, RenderedImage renderedImage, int index)
1253                    throws Exception {
1254    
1255                    if (!isThumbnailEnabled(index) || hasThumbnail(fileVersion, index)) {
1256                            return;
1257                    }
1258    
1259                    String type = getThumbnailType(fileVersion);
1260    
1261                    String maxHeightPropsKey = PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT;
1262                    String maxWidthPropsKey = PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH;
1263    
1264                    if (index == THUMBNAIL_INDEX_CUSTOM_1) {
1265                            maxHeightPropsKey =
1266                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT;
1267                            maxWidthPropsKey =
1268                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH;
1269                    }
1270                    else if (index == THUMBNAIL_INDEX_CUSTOM_2) {
1271                            maxHeightPropsKey =
1272                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT;
1273                            maxWidthPropsKey =
1274                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH;
1275                    }
1276    
1277                    RenderedImage thumbnailRenderedImage = ImageToolUtil.scale(
1278                            renderedImage, PrefsPropsUtil.getInteger(maxHeightPropsKey),
1279                            PrefsPropsUtil.getInteger(maxWidthPropsKey));
1280    
1281                    byte[] bytes = ImageToolUtil.getBytes(thumbnailRenderedImage, type);
1282    
1283                    File file = null;
1284    
1285                    try {
1286                            file = FileUtil.createTempFile(bytes);
1287    
1288                            addFileToStore(
1289                                    fileVersion.getCompanyId(), THUMBNAIL_PATH,
1290                                    getThumbnailFilePath(fileVersion, type, index), file);
1291                    }
1292                    finally {
1293                            FileUtil.delete(file);
1294                    }
1295            }
1296    
1297            protected Map<String, Future<?>> futures =
1298                    new ConcurrentHashMap<String, Future<?>>();
1299    
1300            private static Log _log = LogFactoryUtil.getLog(
1301                    DLPreviewableProcessor.class);
1302    
1303    }