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                            InputStream is = null;
996    
997                            try {
998                                    if (fileIndex < 0) {
999                                            is = doGetPreviewAsStream(fileVersion, previewType);
1000                                    }
1001                                    else {
1002                                            is = doGetPreviewAsStream(
1003                                                    fileVersion, fileIndex, previewType);
1004                                    }
1005    
1006                                    addFileToStore(
1007                                            portletDataContext.getCompanyId(), PREVIEW_PATH,
1008                                            previewFilePath, is);
1009                            }
1010                            finally {
1011                                    StreamUtil.cleanUp(is);
1012                            }
1013                    }
1014            }
1015    
1016            protected void importPreviewFromLAR(
1017                            PortletDataContext portletDataContext, FileEntry fileEntry,
1018                            Element fileEntryElement, String binPathSuffix, String previewType,
1019                            int fileIndex)
1020                    throws Exception {
1021    
1022                    FileVersion fileVersion = fileEntry.getFileVersion();
1023    
1024                    String binPathSegment = null;
1025    
1026                    if (fileIndex < 0) {
1027                            binPathSegment = previewType;
1028                    }
1029                    else {
1030                            binPathSegment = Integer.toString(fileIndex + 1);
1031                    }
1032    
1033                    StringBundler sb = new StringBundler(4);
1034    
1035                    sb.append("bin-path-preview-");
1036                    sb.append(binPathSegment);
1037                    sb.append("-");
1038                    sb.append(binPathSuffix);
1039    
1040                    String binPathName = sb.toString();
1041    
1042                    String binPath = fileEntryElement.attributeValue(binPathName);
1043    
1044                    InputStream is = null;
1045    
1046                    try {
1047                            is = portletDataContext.getZipEntryAsInputStream(binPath);
1048    
1049                            if (is == null) {
1050                                    return;
1051                            }
1052    
1053                            String previewFilePath = null;
1054    
1055                            if (fileIndex < 0) {
1056                                    previewFilePath = getPreviewFilePath(fileVersion, previewType);
1057                            }
1058                            else {
1059                                    previewFilePath = getPreviewFilePath(
1060                                            fileVersion, fileIndex + 1);
1061                            }
1062    
1063                            addFileToStore(
1064                                    portletDataContext.getCompanyId(), PREVIEW_PATH,
1065                                    previewFilePath, is);
1066                    }
1067                    finally {
1068                            StreamUtil.cleanUp(is);
1069                    }
1070            }
1071    
1072            protected void importThumbnail(
1073                            PortletDataContext portletDataContext, FileEntry fileEntry,
1074                            FileEntry importedFileEntry, Element fileEntryElement,
1075                            String binPathName, int index)
1076                    throws Exception {
1077    
1078                    if (!portletDataContext.isPerformDirectBinaryImport()) {
1079                            importThumbnailFromLAR(
1080                                    portletDataContext, importedFileEntry, fileEntryElement,
1081                                    binPathName, index);
1082                    }
1083                    else {
1084                            FileVersion fileVersion = fileEntry.getFileVersion();
1085    
1086                            if (!hasThumbnail(fileVersion, index)) {
1087                                    return;
1088                            }
1089    
1090                            InputStream is = null;
1091    
1092                            try {
1093                                    is = doGetThumbnailAsStream(fileVersion, index);
1094    
1095                                    FileVersion importedFileVersion =
1096                                            importedFileEntry.getFileVersion();
1097    
1098                                    String thumbnailFilePath = getThumbnailFilePath(
1099                                            importedFileVersion, getThumbnailType(importedFileVersion),
1100                                            index);
1101    
1102                                    addFileToStore(
1103                                            portletDataContext.getCompanyId(), THUMBNAIL_PATH,
1104                                            thumbnailFilePath, is);
1105                            }
1106                            finally {
1107                                    StreamUtil.cleanUp(is);
1108                            }
1109                    }
1110            }
1111    
1112            protected void importThumbnailFromLAR(
1113                            PortletDataContext portletDataContext, FileEntry fileEntry,
1114                            Element fileEntryElement, String binPathName, int index)
1115                    throws Exception {
1116    
1117                    FileVersion fileVersion = fileEntry.getFileVersion();
1118    
1119                    String binPath = fileEntryElement.attributeValue(binPathName);
1120    
1121                    InputStream is = null;
1122    
1123                    try {
1124                            is = portletDataContext.getZipEntryAsInputStream(binPath);
1125    
1126                            if (is == null) {
1127                                    return;
1128                            }
1129    
1130                            String thumbnailFilePath = getThumbnailFilePath(
1131                                    fileVersion, getThumbnailType(fileVersion), index);
1132    
1133                            addFileToStore(
1134                                    portletDataContext.getCompanyId(), THUMBNAIL_PATH,
1135                                    thumbnailFilePath, is);
1136                    }
1137                    finally {
1138                            StreamUtil.cleanUp(is);
1139                    }
1140            }
1141    
1142            protected void importThumbnails(
1143                            PortletDataContext portletDataContext, FileEntry fileEntry,
1144                            FileEntry importedFileEntry, Element fileEntryElement,
1145                            String binPathSuffix)
1146                    throws Exception {
1147    
1148                    importThumbnail(
1149                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1150                            "bin-path-thumbnail-default-" + binPathSuffix,
1151                            THUMBNAIL_INDEX_DEFAULT);
1152    
1153                    importThumbnail(
1154                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1155                            "bin-path-thumbnail-custom-1-" + binPathSuffix,
1156                            THUMBNAIL_INDEX_CUSTOM_1);
1157    
1158                    importThumbnail(
1159                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
1160                            "bin-path-thumbnail-custom-2-" + binPathSuffix,
1161                            THUMBNAIL_INDEX_CUSTOM_2);
1162            }
1163    
1164            protected boolean isThumbnailEnabled(int index) throws Exception {
1165                    if (index == THUMBNAIL_INDEX_DEFAULT) {
1166                            if (GetterUtil.getBoolean(
1167                                            PropsUtil.get(
1168                                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_ENABLED))) {
1169    
1170                                    return true;
1171                            }
1172                    }
1173                    else if (index == THUMBNAIL_INDEX_CUSTOM_1) {
1174                            if ((PrefsPropsUtil.getInteger(
1175                                            PropsKeys.
1176                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT) > 0) ||
1177                                    (PrefsPropsUtil.getInteger(
1178                                            PropsKeys.
1179                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH) > 0)) {
1180    
1181                                    return true;
1182                            }
1183                    }
1184                    else if (index == THUMBNAIL_INDEX_CUSTOM_2) {
1185                            if ((PrefsPropsUtil.getInteger(
1186                                            PropsKeys.
1187                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT) > 0) ||
1188                                    (PrefsPropsUtil.getInteger(
1189                                            PropsKeys.
1190                                                    DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH) > 0)) {
1191    
1192                                    return true;
1193                            }
1194                    }
1195    
1196                    return false;
1197            }
1198    
1199            protected void sendGenerationMessage(
1200                    String destinationName, FileVersion sourceFileVersion,
1201                    FileVersion destinationFileVersion) {
1202    
1203                    Object[] payload = {sourceFileVersion, destinationFileVersion};
1204    
1205                    MessageBusUtil.sendMessage(destinationName, payload);
1206            }
1207    
1208            protected void storeThumbnailImages(FileVersion fileVersion, File file)
1209                    throws Exception {
1210    
1211                    ImageBag imageBag = ImageToolUtil.read(file);
1212    
1213                    RenderedImage renderedImage = imageBag.getRenderedImage();
1214    
1215                    storeThumbnailImages(fileVersion, renderedImage);
1216            }
1217    
1218            protected void storeThumbnailImages(
1219                            FileVersion fileVersion, RenderedImage renderedImage)
1220                    throws Exception {
1221    
1222                    storeThumbnailmage(fileVersion, renderedImage, THUMBNAIL_INDEX_DEFAULT);
1223                    storeThumbnailmage(
1224                            fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_1);
1225                    storeThumbnailmage(
1226                            fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_2);
1227            }
1228    
1229            protected void storeThumbnailmage(
1230                            FileVersion fileVersion, RenderedImage renderedImage, int index)
1231                    throws Exception {
1232    
1233                    if (!isThumbnailEnabled(index) || hasThumbnail(fileVersion, index)) {
1234                            return;
1235                    }
1236    
1237                    String type = getThumbnailType(fileVersion);
1238    
1239                    String maxHeightPropsKey = PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT;
1240                    String maxWidthPropsKey = PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH;
1241    
1242                    if (index == THUMBNAIL_INDEX_CUSTOM_1) {
1243                            maxHeightPropsKey =
1244                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_HEIGHT;
1245                            maxWidthPropsKey =
1246                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_1_MAX_WIDTH;
1247                    }
1248                    else if (index == THUMBNAIL_INDEX_CUSTOM_2) {
1249                            maxHeightPropsKey =
1250                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_HEIGHT;
1251                            maxWidthPropsKey =
1252                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_CUSTOM_2_MAX_WIDTH;
1253                    }
1254    
1255                    RenderedImage thumbnailRenderedImage = ImageToolUtil.scale(
1256                            renderedImage, PrefsPropsUtil.getInteger(maxHeightPropsKey),
1257                            PrefsPropsUtil.getInteger(maxWidthPropsKey));
1258    
1259                    byte[] bytes = ImageToolUtil.getBytes(thumbnailRenderedImage, type);
1260    
1261                    File file = null;
1262    
1263                    try {
1264                            file = FileUtil.createTempFile(bytes);
1265    
1266                            addFileToStore(
1267                                    fileVersion.getCompanyId(), THUMBNAIL_PATH,
1268                                    getThumbnailFilePath(fileVersion, type, index), file);
1269                    }
1270                    finally {
1271                            FileUtil.delete(file);
1272                    }
1273            }
1274    
1275            protected Map<String, Future<?>> futures =
1276                    new ConcurrentHashMap<String, Future<?>>();
1277    
1278            private static Log _log = LogFactoryUtil.getLog(
1279                    DLPreviewableProcessor.class);
1280    
1281    }