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