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