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