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.configuration.Filter;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
023    import com.liferay.portal.kernel.portlet.LiferayWindowState;
024    import com.liferay.portal.kernel.repository.model.FileEntry;
025    import com.liferay.portal.kernel.repository.model.FileVersion;
026    import com.liferay.portal.kernel.repository.model.Folder;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.HtmlUtil;
029    import com.liferay.portal.kernel.util.HttpUtil;
030    import com.liferay.portal.kernel.util.OrderByComparator;
031    import com.liferay.portal.kernel.util.ParamUtil;
032    import com.liferay.portal.kernel.util.PrefsParamUtil;
033    import com.liferay.portal.kernel.util.PrefsPropsUtil;
034    import com.liferay.portal.kernel.util.PropsKeys;
035    import com.liferay.portal.kernel.util.PropsUtil;
036    import com.liferay.portal.kernel.util.SetUtil;
037    import com.liferay.portal.kernel.util.StringBundler;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.StringUtil;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.kernel.util.WebKeys;
042    import com.liferay.portal.model.Group;
043    import com.liferay.portal.service.GroupLocalServiceUtil;
044    import com.liferay.portal.theme.ThemeDisplay;
045    import com.liferay.portal.util.PortalUtil;
046    import com.liferay.portlet.PortletPreferencesFactoryUtil;
047    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
048    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
049    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
050    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelCreateDateComparator;
051    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelModifiedDateComparator;
052    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelNameComparator;
053    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelReadCountComparator;
054    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelSizeComparator;
055    
056    import java.util.Arrays;
057    import java.util.Collections;
058    import java.util.Date;
059    import java.util.HashMap;
060    import java.util.HashSet;
061    import java.util.List;
062    import java.util.Map;
063    import java.util.Set;
064    import java.util.TreeSet;
065    
066    import javax.portlet.PortletPreferences;
067    import javax.portlet.PortletRequest;
068    import javax.portlet.PortletURL;
069    import javax.portlet.RenderResponse;
070    
071    import javax.servlet.http.HttpServletRequest;
072    
073    /**
074     * @author Brian Wing Shun Chan
075     * @author Julio Camarero
076     */
077    public class DLUtil {
078    
079            public static void addPortletBreadcrumbEntries(
080                            DLFileShortcut dlFileShortcut, HttpServletRequest request,
081                            RenderResponse renderResponse)
082                    throws Exception {
083    
084                    Folder folder = dlFileShortcut.getFolder();
085    
086                    if (folder.getFolderId() !=
087                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
088    
089                            addPortletBreadcrumbEntries(folder, request, renderResponse);
090                    }
091    
092                    PortletURL portletURL = renderResponse.createRenderURL();
093    
094                    portletURL.setParameter(
095                            "struts_action", "/document_library/view_file_entry");
096                    portletURL.setParameter(
097                            "fileEntryId",
098                            String.valueOf(dlFileShortcut.getToFileEntryId()));
099    
100                    PortalUtil.addPortletBreadcrumbEntry(
101                            request, dlFileShortcut.getToTitle(), portletURL.toString());
102            }
103    
104            public static void addPortletBreadcrumbEntries(
105                            FileEntry fileEntry, HttpServletRequest request,
106                            RenderResponse renderResponse)
107                    throws Exception {
108    
109                    Folder folder = fileEntry.getFolder();
110    
111                    if (folder.getFolderId() !=
112                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
113    
114                            addPortletBreadcrumbEntries(folder, request, renderResponse);
115                    }
116    
117                    PortletURL portletURL = renderResponse.createRenderURL();
118    
119                    portletURL.setParameter(
120                            "struts_action", "/document_library/view_file_entry");
121                    portletURL.setParameter(
122                            "fileEntryId", String.valueOf(fileEntry.getFileEntryId()));
123    
124                    PortalUtil.addPortletBreadcrumbEntry(
125                            request, fileEntry.getTitle(), portletURL.toString());
126            }
127    
128            public static void addPortletBreadcrumbEntries(
129                            Folder folder, HttpServletRequest request,
130                            LiferayPortletResponse liferayPortletResponse)
131                    throws Exception {
132    
133                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
134                            WebKeys.THEME_DISPLAY);
135    
136                    PortletURL portletURL = liferayPortletResponse.createRenderURL();
137    
138                    portletURL.setParameter("struts_action", "/document_library/view");
139                    portletURL.setParameter("viewEntries", Boolean.TRUE.toString());
140                    portletURL.setParameter("viewFolders", Boolean.TRUE.toString());
141    
142                    Map<String, Object> data = new HashMap<String, Object>();
143    
144                    data.put("folder-id", _getDefaultFolderId(request));
145    
146                    PortalUtil.addPortletBreadcrumbEntry(
147                            request, themeDisplay.translate("home"), portletURL.toString(),
148                            data);
149    
150                    addPortletBreadcrumbEntries(folder, request, portletURL);
151            }
152    
153            public static void addPortletBreadcrumbEntries(
154                            Folder folder, HttpServletRequest request, PortletURL portletURL)
155                    throws Exception {
156    
157                    long defaultFolderId = _getDefaultFolderId(request);
158    
159                    List<Folder> ancestorFolders = Collections.emptyList();
160    
161                    if ((folder != null) && (folder.getFolderId() != defaultFolderId)) {
162                            ancestorFolders = folder.getAncestors();
163    
164                            int indexOfRootFolder = -1;
165    
166                            for (int i = 0; i < ancestorFolders.size(); i++) {
167                                    Folder ancestorFolder = ancestorFolders.get(i);
168    
169                                    if (defaultFolderId == ancestorFolder.getFolderId()) {
170                                            indexOfRootFolder = i;
171                                    }
172                            }
173    
174                            if (indexOfRootFolder > -1) {
175                                    ancestorFolders = ancestorFolders.subList(0, indexOfRootFolder);
176                            }
177                    }
178    
179                    Collections.reverse(ancestorFolders);
180    
181                    for (Folder ancestorFolder : ancestorFolders) {
182                            portletURL.setParameter(
183                                    "folderId", String.valueOf(ancestorFolder.getFolderId()));
184    
185                            Map<String, Object> data = new HashMap<String, Object>();
186    
187                            data.put("folder-id", ancestorFolder.getFolderId());
188    
189                            PortalUtil.addPortletBreadcrumbEntry(
190                                    request, ancestorFolder.getName(), portletURL.toString(), data);
191                    }
192    
193                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
194    
195                    if (folder != null) {
196                            folderId = folder.getFolderId();
197                    }
198    
199                    portletURL.setParameter("folderId", String.valueOf(folderId));
200    
201                    if ((folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
202                            (folderId != defaultFolderId)) {
203    
204                            Map<String, Object> data = new HashMap<String, Object>();
205    
206                            data.put("folder-id", folderId);
207    
208                            PortalUtil.addPortletBreadcrumbEntry(
209                                    request, folder.getName(), portletURL.toString(), data);
210                    }
211            }
212    
213            public static void addPortletBreadcrumbEntries(
214                            Folder folder, HttpServletRequest request,
215                            RenderResponse renderResponse)
216                    throws Exception {
217    
218                    String strutsAction = ParamUtil.getString(request, "struts_action");
219    
220                    long groupId = ParamUtil.getLong(request, "groupId");
221    
222                    PortletURL portletURL = renderResponse.createRenderURL();
223    
224                    if (strutsAction.equals("/journal/select_document_library") ||
225                            strutsAction.equals("/document_library/select_file_entry") ||
226                            strutsAction.equals("/document_library/select_folder") ||
227                            strutsAction.equals("/document_library_display/select_folder") ||
228                            strutsAction.equals("/image_gallery_display/select_folder")) {
229    
230                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
231                                    WebKeys.THEME_DISPLAY);
232    
233                            portletURL.setWindowState(LiferayWindowState.POP_UP);
234    
235                            portletURL.setParameter("struts_action", strutsAction);
236                            portletURL.setParameter("groupId", String.valueOf(groupId));
237    
238                            Map<String, Object> data = new HashMap<String, Object>();
239    
240                            data.put("folder-id", _getDefaultFolderId(request));
241                            data.put("view-entries", Boolean.TRUE.toString());
242                            data.put("view-folders", Boolean.TRUE.toString());
243    
244                            PortalUtil.addPortletBreadcrumbEntry(
245                                    request, themeDisplay.translate("home"), portletURL.toString(),
246                                    data);
247                    }
248                    else {
249                            portletURL.setParameter("struts_action", "/document_library/view");
250                    }
251    
252                    addPortletBreadcrumbEntries(folder, request, portletURL);
253            }
254    
255            public static void addPortletBreadcrumbEntries(
256                            long folderId, HttpServletRequest request,
257                            RenderResponse renderResponse)
258                    throws Exception {
259    
260                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
261                            Folder folder = DLAppLocalServiceUtil.getFolder(folderId);
262    
263                            if (folder.getFolderId() !=
264                                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
265    
266                                    addPortletBreadcrumbEntries(folder, request, renderResponse);
267                            }
268                    }
269            }
270    
271            public static int compareVersions(String version1, String version2) {
272                    int[] splitVersion1 = StringUtil.split(version1, StringPool.PERIOD, 0);
273                    int[] splitVersion2 = StringUtil.split(version2, StringPool.PERIOD, 0);
274    
275                    if ((splitVersion1.length != 2) && (splitVersion2.length != 2)) {
276                            return 0;
277                    }
278                    else if ((splitVersion1.length != 2)) {
279                            return -1;
280                    }
281                    else if ((splitVersion2.length != 2)) {
282                            return 1;
283                    }
284    
285                    if (splitVersion1[0] > splitVersion2[0]) {
286                            return 1;
287                    }
288                    else if (splitVersion1[0] < splitVersion2[0]) {
289                            return -1;
290                    }
291                    else if (splitVersion1[1] > splitVersion2[1]) {
292                            return 1;
293                    }
294                    else if (splitVersion1[1] < splitVersion2[1]) {
295                            return -1;
296                    }
297    
298                    return 0;
299            }
300    
301            public static Set<String> getAllMediaGalleryMimeTypes() {
302                    return _instance._allMediaGalleryMimeTypes;
303            }
304    
305            public static String getDividedPath(long id) {
306                    StringBundler sb = new StringBundler(16);
307    
308                    long dividend = id;
309    
310                    while ((dividend / _DIVISOR) != 0) {
311                            sb.append(StringPool.SLASH);
312                            sb.append(dividend % _DIVISOR);
313    
314                            dividend = dividend / _DIVISOR;
315                    }
316    
317                    sb.append(StringPool.SLASH);
318                    sb.append(id);
319    
320                    return sb.toString();
321            }
322    
323            public static String getFileEntryImage(
324                    FileEntry fileEntry, ThemeDisplay themeDisplay) {
325    
326                    StringBundler sb = new StringBundler(5);
327    
328                    sb.append("<img style=\"border-width: 0; text-align: left;\" src=\"");
329                    sb.append(themeDisplay.getPathThemeImages());
330                    sb.append("/file_system/small/");
331                    sb.append(fileEntry.getIcon());
332                    sb.append(".png\">");
333    
334                    return sb.toString();
335            }
336    
337            public static String getFileIcon(String extension) {
338                    return _instance._getFileIcon(extension);
339            }
340    
341            public static String getGenericName(String extension) {
342                    return _instance._getGenericName(extension);
343            }
344    
345            public static long[] getGroupIds(long groupId)
346                    throws PortalException, SystemException {
347    
348                    Group scopeGroup = GroupLocalServiceUtil.getGroup(groupId);
349    
350                    Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
351                            scopeGroup.getCompanyId());
352    
353                    if (scopeGroup.isLayout()) {
354                            return new long[] {
355                                    scopeGroup.getParentGroupId(), companyGroup.getGroupId()
356                            };
357                    }
358                    else {
359                            return new long[] {groupId, companyGroup.getGroupId()};
360                    }
361            }
362    
363            public static long[] getGroupIds(ThemeDisplay themeDisplay)
364                    throws PortalException, SystemException {
365    
366                    return getGroupIds(themeDisplay.getScopeGroupId());
367            }
368    
369            public static String[] getMediaGalleryMimeTypes(
370                    PortletPreferences portletPreferences, PortletRequest portletRequest) {
371    
372                    String mimeTypes = PrefsParamUtil.getString(
373                            portletPreferences, portletRequest, "mimeTypes",
374                            _instance._allMediaGalleryMimeTypesString);
375    
376                    String[] mimeTypesArray = StringUtil.split(mimeTypes);
377    
378                    Arrays.sort(mimeTypesArray);
379    
380                    return mimeTypesArray;
381            }
382    
383            public static String getPreviewURL(
384                    FileEntry fileEntry, FileVersion fileVersion, ThemeDisplay themeDisplay,
385                    String queryString) {
386    
387                    return getPreviewURL(
388                            fileEntry, fileVersion, themeDisplay, queryString, true);
389            }
390    
391            public static String getPreviewURL(
392                    FileEntry fileEntry, FileVersion fileVersion, ThemeDisplay themeDisplay,
393                    String queryString, boolean appendToken) {
394    
395                    StringBundler sb = new StringBundler(13);
396    
397                    sb.append(themeDisplay.getPortalURL());
398                    sb.append(themeDisplay.getPathContext());
399                    sb.append("/documents/");
400                    sb.append(fileEntry.getRepositoryId());
401                    sb.append(StringPool.SLASH);
402                    sb.append(fileEntry.getFolderId());
403                    sb.append(StringPool.SLASH);
404                    sb.append(
405                            HttpUtil.encodeURL(HtmlUtil.unescape(fileEntry.getTitle()), true));
406                    sb.append("?version=");
407                    sb.append(fileVersion.getVersion());
408    
409                    if (appendToken) {
410                            sb.append("&t=");
411    
412                            Date modifiedDate = fileVersion.getModifiedDate();
413    
414                            sb.append(modifiedDate.getTime());
415                    }
416    
417                    sb.append(queryString);
418    
419                    String previewURL = sb.toString();
420    
421                    if (themeDisplay.isAddSessionIdToURL()) {
422                            return PortalUtil.getURLWithSessionId(
423                                    previewURL, themeDisplay.getSessionId());
424                    }
425    
426                    return previewURL;
427            }
428    
429            public static OrderByComparator getRepositoryModelOrderByComparator(
430                    String orderByCol, String orderByType) {
431    
432                    boolean orderByAsc = true;
433    
434                    if (orderByType.equals("desc")) {
435                            orderByAsc = false;
436                    }
437    
438                    OrderByComparator orderByComparator = null;
439    
440                    if (orderByCol.equals("creationDate")) {
441                            orderByComparator = new RepositoryModelCreateDateComparator(
442                                    orderByAsc);
443                    }
444                    else if (orderByCol.equals("downloads")) {
445                            orderByComparator = new RepositoryModelReadCountComparator(
446                                    orderByAsc);
447                    }
448                    else if (orderByCol.equals("modifiedDate")) {
449                            orderByComparator = new RepositoryModelModifiedDateComparator(
450                                    orderByAsc);
451                    }
452                    else if (orderByCol.equals("size")) {
453                            orderByComparator = new RepositoryModelSizeComparator(orderByAsc);
454                    }
455                    else {
456                            orderByComparator = new RepositoryModelNameComparator(orderByAsc);
457                    }
458    
459                    return orderByComparator;
460            }
461    
462            public static String getTempFileId(long id, String version) {
463                    return getTempFileId(id, version, null);
464            }
465    
466            public static String getTempFileId(
467                    long id, String version, String languageId) {
468    
469                    if (Validator.isNull(languageId)) {
470                            return String.valueOf(id).concat(StringPool.PERIOD).concat(version);
471                    }
472    
473                    StringBundler sb = new StringBundler(5);
474    
475                    sb.append(id);
476                    sb.append(StringPool.PERIOD);
477                    sb.append(version);
478                    sb.append(StringPool.PERIOD);
479                    sb.append(languageId);
480    
481                    return sb.toString();
482            }
483    
484            public static String getThumbnailSrc(
485                            FileEntry fileEntry, DLFileShortcut fileShortcut,
486                            ThemeDisplay themeDisplay)
487                    throws Exception {
488    
489                    FileVersion fileVersion = fileEntry.getFileVersion();
490    
491                    StringBundler sb = new StringBundler(4);
492    
493                    sb.append(themeDisplay.getPathThemeImages());
494                    sb.append("/file_system/large/");
495                    sb.append(DLUtil.getGenericName(fileEntry.getExtension()));
496                    sb.append(".png");
497    
498                    String thumbnailSrc = sb.toString();
499    
500                    if (fileShortcut == null) {
501                            String thumbnailQueryString = null;
502    
503                            if (ImageProcessorUtil.hasImages(fileVersion)) {
504                                    thumbnailQueryString = "&imageThumbnail=1";
505                            }
506                            else if (PDFProcessorUtil.hasImages(fileVersion)) {
507                                    thumbnailQueryString = "&documentThumbnail=1";
508                            }
509                            else if (VideoProcessorUtil.hasVideo(fileVersion)) {
510                                    thumbnailQueryString = "&videoThumbnail=1";
511                            }
512    
513                            if (Validator.isNotNull(thumbnailQueryString)) {
514                                    thumbnailSrc = getPreviewURL(
515                                            fileEntry, fileVersion, themeDisplay, thumbnailQueryString);
516                            }
517                    }
518    
519                    return thumbnailSrc;
520            }
521    
522            public static String getThumbnailStyle() throws Exception {
523                    StringBundler sb = new StringBundler(5);
524    
525                    sb.append("max-height: ");
526                    sb.append(
527                            PrefsPropsUtil.getLong(
528                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT));
529                    sb.append("px; max-width: ");
530                    sb.append(
531                            PrefsPropsUtil.getLong(
532                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH));
533                    sb.append("px;");
534    
535                    return sb.toString();
536            }
537    
538            private static long _getDefaultFolderId(HttpServletRequest request)
539                    throws Exception {
540    
541                    PortletPreferences portletPreferences =
542                            PortletPreferencesFactoryUtil.getPortletPreferences(
543                                    request, PortalUtil.getPortletId(request));
544    
545                    return GetterUtil.getLong(
546                            portletPreferences.getValue(
547                                    "rootFolderId",
548                                    String.valueOf(DLFolderConstants.DEFAULT_PARENT_FOLDER_ID)));
549            }
550    
551            private DLUtil() {
552                    _allMediaGalleryMimeTypes.addAll(
553                            SetUtil.fromArray(
554                                    PropsUtil.getArray(
555                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_AUDIO_MIME_TYPES)));
556                    _allMediaGalleryMimeTypes.addAll(
557                            SetUtil.fromArray(
558                                    PropsUtil.getArray(
559                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO_MIME_TYPES)));
560                    _allMediaGalleryMimeTypes.addAll(
561                            SetUtil.fromArray(
562                                    PropsUtil.getArray(
563                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_IMAGE_MIME_TYPES)));
564    
565                    _allMediaGalleryMimeTypesString = StringUtil.merge(
566                            _allMediaGalleryMimeTypes);
567    
568                    String[] fileIcons = null;
569    
570                    try {
571                            fileIcons = PrefsPropsUtil.getStringArray(
572                                    PropsKeys.DL_FILE_ICONS, StringPool.COMMA);
573                    }
574                    catch (Exception e) {
575                            _log.error(e, e);
576    
577                            fileIcons = new String[] {StringPool.BLANK};
578                    }
579    
580                    for (int i = 0; i < fileIcons.length; i++) {
581    
582                            // Only process non wildcard extensions
583    
584                            if (!StringPool.STAR.equals(fileIcons[i])) {
585    
586                                    // Strip starting period
587    
588                                    String extension = fileIcons[i];
589                                    extension = extension.substring(1, extension.length());
590    
591                                    _fileIcons.add(extension);
592                            }
593                    }
594    
595                    String[] genericNames = PropsUtil.getArray(
596                            PropsKeys.DL_FILE_GENERIC_NAMES);
597    
598                    for (String genericName : genericNames) {
599                            _populateGenericNamesMap(genericName);
600                    }
601            }
602    
603            private String _getFileIcon(String extension) {
604                    if (!_fileIcons.contains(extension)) {
605                            extension = _DEFAULT_FILE_ICON;
606                    }
607    
608                    return extension;
609            }
610    
611            private String _getGenericName(String extension) {
612                    String genericName = _genericNames.get(extension);
613    
614                    if (genericName == null) {
615                            genericName = _DEFAULT_GENERIC_NAME;
616                    }
617    
618                    return genericName;
619            }
620    
621            private void _populateGenericNamesMap(String genericName) {
622                    String[] extensions = PropsUtil.getArray(
623                            PropsKeys.DL_FILE_GENERIC_EXTENSIONS, new Filter(genericName));
624    
625                    for (String extension : extensions) {
626                            _genericNames.put(extension, genericName);
627                    }
628            }
629    
630            private static final String _DEFAULT_FILE_ICON = "page";
631    
632            private static final String _DEFAULT_GENERIC_NAME = "default";
633    
634            private static final long _DIVISOR = 256;;
635    
636            private static Log _log = LogFactoryUtil.getLog(DLUtil.class);
637    
638            private static DLUtil _instance = new DLUtil();
639    
640            private Set<String> _allMediaGalleryMimeTypes = new TreeSet<String>();
641            private String _allMediaGalleryMimeTypesString;
642            private Set<String> _fileIcons = new HashSet<String>();
643            private Map<String, String> _genericNames = new HashMap<String, String>();
644    
645    }