001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.util;
016    
017    import com.liferay.portal.kernel.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.search.Document;
028    import com.liferay.portal.kernel.search.Field;
029    import com.liferay.portal.kernel.search.Hits;
030    import com.liferay.portal.kernel.util.ArrayUtil;
031    import com.liferay.portal.kernel.util.GetterUtil;
032    import com.liferay.portal.kernel.util.HtmlUtil;
033    import com.liferay.portal.kernel.util.HttpUtil;
034    import com.liferay.portal.kernel.util.LocaleUtil;
035    import com.liferay.portal.kernel.util.LocalizationUtil;
036    import com.liferay.portal.kernel.util.OrderByComparator;
037    import com.liferay.portal.kernel.util.ParamUtil;
038    import com.liferay.portal.kernel.util.PrefsParamUtil;
039    import com.liferay.portal.kernel.util.PrefsPropsUtil;
040    import com.liferay.portal.kernel.util.PropsKeys;
041    import com.liferay.portal.kernel.util.PropsUtil;
042    import com.liferay.portal.kernel.util.SetUtil;
043    import com.liferay.portal.kernel.util.StringBundler;
044    import com.liferay.portal.kernel.util.StringPool;
045    import com.liferay.portal.kernel.util.StringUtil;
046    import com.liferay.portal.kernel.util.Validator;
047    import com.liferay.portal.kernel.util.WebKeys;
048    import com.liferay.portal.kernel.workflow.WorkflowConstants;
049    import com.liferay.portal.model.Group;
050    import com.liferay.portal.model.Subscription;
051    import com.liferay.portal.service.SubscriptionLocalServiceUtil;
052    import com.liferay.portal.service.WorkflowDefinitionLinkLocalServiceUtil;
053    import com.liferay.portal.theme.PortletDisplay;
054    import com.liferay.portal.theme.ThemeDisplay;
055    import com.liferay.portal.util.PortalUtil;
056    import com.liferay.portal.util.PortletKeys;
057    import com.liferay.portal.util.PropsValues;
058    import com.liferay.portlet.PortletPreferencesFactoryUtil;
059    import com.liferay.portlet.PortletURLFactoryUtil;
060    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
061    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
062    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
063    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
064    import com.liferay.portlet.documentlibrary.model.DLFolder;
065    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
066    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
067    import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
068    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelCreateDateComparator;
069    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelModifiedDateComparator;
070    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelNameComparator;
071    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelReadCountComparator;
072    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelSizeComparator;
073    import com.liferay.portlet.messageboards.model.MBMessage;
074    import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
075    import com.liferay.portlet.trash.util.TrashUtil;
076    import com.liferay.util.ContentUtil;
077    
078    import java.util.ArrayList;
079    import java.util.Arrays;
080    import java.util.Collections;
081    import java.util.Date;
082    import java.util.HashMap;
083    import java.util.HashSet;
084    import java.util.List;
085    import java.util.Locale;
086    import java.util.Map;
087    import java.util.Set;
088    import java.util.TreeSet;
089    
090    import javax.portlet.PortletPreferences;
091    import javax.portlet.PortletRequest;
092    import javax.portlet.PortletURL;
093    import javax.portlet.RenderResponse;
094    
095    import javax.servlet.http.HttpServletRequest;
096    
097    /**
098     * @author Brian Wing Shun Chan
099     * @author Julio Camarero
100     */
101    public class DLImpl implements DL {
102    
103            @Override
104            public void addPortletBreadcrumbEntries(
105                            DLFileShortcut dlFileShortcut, HttpServletRequest request,
106                            RenderResponse renderResponse)
107                    throws Exception {
108    
109                    Folder folder = dlFileShortcut.getFolder();
110    
111                    if (folder.getFolderId() !=
112                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
113    
114                            addPortletBreadcrumbEntries(folder, request, renderResponse);
115                    }
116    
117                    DLFileShortcut unescapedDLFileShortcut =
118                            dlFileShortcut.toUnescapedModel();
119    
120                    PortletURL portletURL = renderResponse.createRenderURL();
121    
122                    portletURL.setParameter(
123                            "struts_action", "/document_library/view_file_entry");
124                    portletURL.setParameter(
125                            "fileEntryId", String.valueOf(dlFileShortcut.getToFileEntryId()));
126    
127                    PortalUtil.addPortletBreadcrumbEntry(
128                            request, unescapedDLFileShortcut.getToTitle(),
129                            portletURL.toString());
130            }
131    
132            @Override
133            public void addPortletBreadcrumbEntries(
134                            FileEntry fileEntry, HttpServletRequest request,
135                            RenderResponse renderResponse)
136                    throws Exception {
137    
138                    Folder folder = fileEntry.getFolder();
139    
140                    if (folder.getFolderId() !=
141                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
142    
143                            addPortletBreadcrumbEntries(folder, request, renderResponse);
144                    }
145    
146                    PortletURL portletURL = renderResponse.createRenderURL();
147    
148                    FileEntry unescapedFileEntry = fileEntry.toUnescapedModel();
149    
150                    portletURL.setParameter(
151                            "struts_action", "/document_library/view_file_entry");
152                    portletURL.setParameter(
153                            "fileEntryId", String.valueOf(fileEntry.getFileEntryId()));
154    
155                    PortalUtil.addPortletBreadcrumbEntry(
156                            request, unescapedFileEntry.getTitle(), portletURL.toString());
157            }
158    
159            @Override
160            public void addPortletBreadcrumbEntries(
161                            Folder folder, HttpServletRequest request,
162                            LiferayPortletResponse liferayPortletResponse)
163                    throws Exception {
164    
165                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
166                            WebKeys.THEME_DISPLAY);
167    
168                    PortletURL portletURL = liferayPortletResponse.createRenderURL();
169    
170                    portletURL.setParameter("struts_action", "/document_library/view");
171    
172                    Map<String, Object> data = new HashMap<String, Object>();
173    
174                    data.put("direction-right", Boolean.TRUE.toString());
175                    data.put("folder-id", getDefaultFolderId(request));
176    
177                    PortalUtil.addPortletBreadcrumbEntry(
178                            request, themeDisplay.translate("home"), portletURL.toString(),
179                            data);
180    
181                    addPortletBreadcrumbEntries(folder, request, portletURL);
182            }
183    
184            @Override
185            public void addPortletBreadcrumbEntries(
186                            Folder folder, HttpServletRequest request, PortletURL portletURL)
187                    throws Exception {
188    
189                    long defaultFolderId = getDefaultFolderId(request);
190    
191                    List<Folder> ancestorFolders = Collections.emptyList();
192    
193                    if ((folder != null) && (folder.getFolderId() != defaultFolderId)) {
194                            ancestorFolders = folder.getAncestors();
195    
196                            int indexOfRootFolder = -1;
197    
198                            for (int i = 0; i < ancestorFolders.size(); i++) {
199                                    Folder ancestorFolder = ancestorFolders.get(i);
200    
201                                    if (defaultFolderId == ancestorFolder.getFolderId()) {
202                                            indexOfRootFolder = i;
203                                    }
204                            }
205    
206                            if (indexOfRootFolder > -1) {
207                                    ancestorFolders = ancestorFolders.subList(0, indexOfRootFolder);
208                            }
209                    }
210    
211                    Collections.reverse(ancestorFolders);
212    
213                    for (Folder ancestorFolder : ancestorFolders) {
214                            portletURL.setParameter(
215                                    "folderId", String.valueOf(ancestorFolder.getFolderId()));
216    
217                            Map<String, Object> data = new HashMap<String, Object>();
218    
219                            data.put("direction-right", Boolean.TRUE.toString());
220                            data.put("folder-id", ancestorFolder.getFolderId());
221    
222                            PortalUtil.addPortletBreadcrumbEntry(
223                                    request, ancestorFolder.getName(), portletURL.toString(), data);
224                    }
225    
226                    long folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
227    
228                    if (folder != null) {
229                            folderId = folder.getFolderId();
230                    }
231    
232                    portletURL.setParameter("folderId", String.valueOf(folderId));
233    
234                    if ((folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
235                            (folderId != defaultFolderId)) {
236    
237                            Folder unescapedFolder = folder.toUnescapedModel();
238    
239                            Map<String, Object> data = new HashMap<String, Object>();
240    
241                            data.put("direction-right", Boolean.TRUE.toString());
242                            data.put("folder-id", folderId);
243    
244                            PortalUtil.addPortletBreadcrumbEntry(
245                                    request, unescapedFolder.getName(), portletURL.toString(),
246                                    data);
247                    }
248            }
249    
250            @Override
251            public void addPortletBreadcrumbEntries(
252                            Folder folder, HttpServletRequest request,
253                            RenderResponse renderResponse)
254                    throws Exception {
255    
256                    String strutsAction = ParamUtil.getString(request, "struts_action");
257    
258                    long groupId = ParamUtil.getLong(request, "groupId");
259    
260                    PortletURL portletURL = renderResponse.createRenderURL();
261    
262                    if (strutsAction.equals("/document_library/select_file_entry") ||
263                            strutsAction.equals("/document_library/select_folder") ||
264                            strutsAction.equals("/document_library_display/select_folder") ||
265                            strutsAction.equals(
266                                    "/dynamic_data_mapping/select_document_library") ||
267                            strutsAction.equals("/image_gallery_display/select_folder")) {
268    
269                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
270                                    WebKeys.THEME_DISPLAY);
271    
272                            portletURL.setParameter("struts_action", strutsAction);
273                            portletURL.setParameter("groupId", String.valueOf(groupId));
274                            portletURL.setWindowState(LiferayWindowState.POP_UP);
275    
276                            PortalUtil.addPortletBreadcrumbEntry(
277                                    request, themeDisplay.translate("home"), portletURL.toString());
278                    }
279                    else {
280                            portletURL.setParameter("struts_action", "/document_library/view");
281                    }
282    
283                    addPortletBreadcrumbEntries(folder, request, portletURL);
284            }
285    
286            @Override
287            public void addPortletBreadcrumbEntries(
288                            long folderId, HttpServletRequest request,
289                            RenderResponse renderResponse)
290                    throws Exception {
291    
292                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
293                            Folder folder = DLAppLocalServiceUtil.getFolder(folderId);
294    
295                            if (folder.getFolderId() !=
296                                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
297    
298                                    addPortletBreadcrumbEntries(folder, request, renderResponse);
299                            }
300                    }
301            }
302    
303            @Override
304            public int compareVersions(String version1, String version2) {
305                    int[] splitVersion1 = StringUtil.split(version1, StringPool.PERIOD, 0);
306                    int[] splitVersion2 = StringUtil.split(version2, StringPool.PERIOD, 0);
307    
308                    if ((splitVersion1.length != 2) && (splitVersion2.length != 2)) {
309                            return 0;
310                    }
311                    else if (splitVersion1.length != 2) {
312                            return -1;
313                    }
314                    else if (splitVersion2.length != 2) {
315                            return 1;
316                    }
317    
318                    if (splitVersion1[0] > splitVersion2[0]) {
319                            return 1;
320                    }
321                    else if (splitVersion1[0] < splitVersion2[0]) {
322                            return -1;
323                    }
324                    else if (splitVersion1[1] > splitVersion2[1]) {
325                            return 1;
326                    }
327                    else if (splitVersion1[1] < splitVersion2[1]) {
328                            return -1;
329                    }
330    
331                    return 0;
332            }
333    
334            @Override
335            public String getAbsolutePath(PortletRequest portletRequest, long folderId)
336                    throws PortalException, SystemException {
337    
338                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
339                            WebKeys.THEME_DISPLAY);
340    
341                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
342                            return themeDisplay.translate("home");
343                    }
344    
345                    DLFolder dlFolder = DLFolderLocalServiceUtil.getFolder(folderId);
346    
347                    List<DLFolder> dlFolders = dlFolder.getAncestors();
348    
349                    Collections.reverse(dlFolders);
350    
351                    StringBundler sb = new StringBundler((dlFolders.size() * 3) + 5);
352    
353                    sb.append(themeDisplay.translate("home"));
354                    sb.append(StringPool.SPACE);
355    
356                    for (DLFolder curDLFolder : dlFolders) {
357                            sb.append(StringPool.RAQUO);
358                            sb.append(StringPool.SPACE);
359                            sb.append(curDLFolder.getName());
360                    }
361    
362                    sb.append(StringPool.RAQUO);
363                    sb.append(StringPool.SPACE);
364                    sb.append(dlFolder.getName());
365    
366                    return sb.toString();
367            }
368    
369            @Override
370            public Set<String> getAllMediaGalleryMimeTypes() {
371                    return _allMediaGalleryMimeTypes;
372            }
373    
374            @Override
375            public String getDDMStructureKey(DLFileEntryType dlFileEntryType) {
376                    return getDDMStructureKey(dlFileEntryType.getUuid());
377            }
378    
379            @Override
380            public String getDDMStructureKey(String fileEntryTypeUuid) {
381                    return _STRUCTURE_KEY_PREFIX +
382                            StringUtil.toUpperCase(fileEntryTypeUuid);
383            }
384    
385            @Override
386            public String getDeprecatedDDMStructureKey(
387                    DLFileEntryType dlFileEntryType) {
388    
389                    return getDeprecatedDDMStructureKey(
390                            dlFileEntryType.getFileEntryTypeId());
391            }
392    
393            @Override
394            public String getDeprecatedDDMStructureKey(long fileEntryTypeId) {
395                    return _STRUCTURE_KEY_PREFIX + fileEntryTypeId;
396            }
397    
398            @Override
399            public String getDividedPath(long id) {
400                    StringBundler sb = new StringBundler(16);
401    
402                    long dividend = id;
403    
404                    while ((dividend / _DIVISOR) != 0) {
405                            sb.append(StringPool.SLASH);
406                            sb.append(dividend % _DIVISOR);
407    
408                            dividend = dividend / _DIVISOR;
409                    }
410    
411                    sb.append(StringPool.SLASH);
412                    sb.append(id);
413    
414                    return sb.toString();
415            }
416    
417            @Override
418            public String getDLFileEntryControlPanelLink(
419                            PortletRequest portletRequest, long fileEntryId)
420                    throws PortalException, SystemException {
421    
422                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
423                            WebKeys.THEME_DISPLAY);
424    
425                    PortletURL portletURL = PortletURLFactoryUtil.create(
426                            portletRequest, PortletKeys.DOCUMENT_LIBRARY,
427                            PortalUtil.getControlPanelPlid(themeDisplay.getCompanyId()),
428                            PortletRequest.RENDER_PHASE);
429    
430                    portletURL.setParameter(
431                            "struts_action", "/document_library/view_file_entry");
432                    portletURL.setParameter("fileEntryId", String.valueOf(fileEntryId));
433    
434                    return portletURL.toString();
435            }
436    
437            @Override
438            public String getDLFolderControlPanelLink(
439                            PortletRequest portletRequest, long folderId)
440                    throws PortalException, SystemException {
441    
442                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
443                            WebKeys.THEME_DISPLAY);
444    
445                    PortletURL portletURL = PortletURLFactoryUtil.create(
446                            portletRequest, PortletKeys.DOCUMENT_LIBRARY,
447                            PortalUtil.getControlPanelPlid(themeDisplay.getCompanyId()),
448                            PortletRequest.RENDER_PHASE);
449    
450                    portletURL.setParameter("struts_action", "/document_library/view");
451                    portletURL.setParameter("folderId", String.valueOf(folderId));
452    
453                    return portletURL.toString();
454            }
455    
456            @Override
457            public Map<Locale, String> getEmailFileEntryAddedBodyMap(
458                    PortletPreferences preferences) {
459    
460                    Map<Locale, String> map = LocalizationUtil.getLocalizationMap(
461                            preferences, "emailFileEntryAddedBody");
462    
463                    Locale defaultLocale = LocaleUtil.getSiteDefault();
464    
465                    String defaultValue = map.get(defaultLocale);
466    
467                    if (Validator.isNotNull(defaultValue)) {
468                            return map;
469                    }
470    
471                    map.put(
472                            defaultLocale,
473                            ContentUtil.get(
474                                    PropsUtil.get(PropsKeys.DL_EMAIL_FILE_ENTRY_ADDED_BODY)));
475    
476                    return map;
477            }
478    
479            @Override
480            public boolean getEmailFileEntryAddedEnabled(
481                    PortletPreferences preferences) {
482    
483                    String emailFileEntryAddedEnabled = preferences.getValue(
484                            "emailFileEntryAddedEnabled", StringPool.BLANK);
485    
486                    if (Validator.isNotNull(emailFileEntryAddedEnabled)) {
487                            return GetterUtil.getBoolean(emailFileEntryAddedEnabled);
488                    }
489                    else {
490                            return PropsValues.DL_EMAIL_FILE_ENTRY_ADDED_ENABLED;
491                    }
492            }
493    
494            @Override
495            public Map<Locale, String> getEmailFileEntryAddedSubjectMap(
496                    PortletPreferences preferences) {
497    
498                    Map<Locale, String> map = LocalizationUtil.getLocalizationMap(
499                            preferences, "emailFileEntryAddedSubject");
500    
501                    Locale defaultLocale = LocaleUtil.getSiteDefault();
502    
503                    String defaultValue = map.get(defaultLocale);
504    
505                    if (Validator.isNotNull(defaultValue)) {
506                            return map;
507                    }
508    
509                    map.put(
510                            defaultLocale,
511                            ContentUtil.get(
512                                    PropsUtil.get(PropsKeys.DL_EMAIL_FILE_ENTRY_ADDED_SUBJECT)));
513    
514                    return map;
515            }
516    
517            @Override
518            public Map<Locale, String> getEmailFileEntryUpdatedBodyMap(
519                    PortletPreferences preferences) {
520    
521                    Map<Locale, String> map = LocalizationUtil.getLocalizationMap(
522                            preferences, "emailFileEntryUpdatedBody");
523    
524                    Locale defaultLocale = LocaleUtil.getSiteDefault();
525    
526                    String defaultValue = map.get(defaultLocale);
527    
528                    if (Validator.isNotNull(defaultValue)) {
529                            return map;
530                    }
531    
532                    map.put(
533                            defaultLocale,
534                            ContentUtil.get(
535                                    PropsUtil.get(PropsKeys.DL_EMAIL_FILE_ENTRY_UPDATED_BODY)));
536    
537                    return map;
538            }
539    
540            @Override
541            public boolean getEmailFileEntryUpdatedEnabled(
542                    PortletPreferences preferences) {
543    
544                    String emailFileEntryUpdatedEnabled = preferences.getValue(
545                            "emailFileEntryUpdatedEnabled", StringPool.BLANK);
546    
547                    if (Validator.isNotNull(emailFileEntryUpdatedEnabled)) {
548                            return GetterUtil.getBoolean(emailFileEntryUpdatedEnabled);
549                    }
550                    else {
551                            return PropsValues.DL_EMAIL_FILE_ENTRY_UPDATED_ENABLED;
552                    }
553            }
554    
555            @Override
556            public Map<Locale, String> getEmailFileEntryUpdatedSubjectMap(
557                    PortletPreferences preferences) {
558    
559                    Map<Locale, String> map = LocalizationUtil.getLocalizationMap(
560                            preferences, "emailFileEntryUpdatedSubject");
561    
562                    Locale defaultLocale = LocaleUtil.getSiteDefault();
563    
564                    String defaultValue = map.get(defaultLocale);
565    
566                    if (Validator.isNotNull(defaultValue)) {
567                            return map;
568                    }
569    
570                    map.put(
571                            defaultLocale,
572                            ContentUtil.get(
573                                    PropsUtil.get(PropsKeys.DL_EMAIL_FILE_ENTRY_UPDATED_SUBJECT)));
574    
575                    return map;
576            }
577    
578            @Override
579            public String getEmailFromAddress(
580                            PortletPreferences preferences, long companyId)
581                    throws SystemException {
582    
583                    return PortalUtil.getEmailFromAddress(
584                            preferences, companyId, PropsValues.DL_EMAIL_FROM_ADDRESS);
585            }
586    
587            @Override
588            public String getEmailFromName(
589                            PortletPreferences preferences, long companyId)
590                    throws SystemException {
591    
592                    return PortalUtil.getEmailFromName(
593                            preferences, companyId, PropsValues.DL_EMAIL_FROM_NAME);
594            }
595    
596            @Override
597            public List<Object> getEntries(Hits hits) {
598                    List<Object> entries = new ArrayList<Object>();
599    
600                    for (Document document : hits.getDocs()) {
601                            String entryClassName = GetterUtil.getString(
602                                    document.get(Field.ENTRY_CLASS_NAME));
603                            long entryClassPK = GetterUtil.getLong(
604                                    document.get(Field.ENTRY_CLASS_PK));
605    
606                            try {
607                                    Object obj = null;
608    
609                                    if (entryClassName.equals(DLFileEntry.class.getName())) {
610                                            obj = DLAppLocalServiceUtil.getFileEntry(entryClassPK);
611                                    }
612                                    else if (entryClassName.equals(MBMessage.class.getName())) {
613                                            long classPK = GetterUtil.getLong(
614                                                    document.get(Field.CLASS_PK));
615    
616                                            DLAppLocalServiceUtil.getFileEntry(classPK);
617    
618                                            obj = MBMessageLocalServiceUtil.getMessage(entryClassPK);
619                                    }
620    
621                                    entries.add(obj);
622                            }
623                            catch (Exception e) {
624                                    if (_log.isWarnEnabled()) {
625                                            _log.warn(
626                                                    "Documents and Media search index is stale and " +
627                                                            "contains entry {className=" + entryClassName +
628                                                                    ", classPK=" + entryClassPK + "}");
629                                    }
630                            }
631                    }
632    
633                    return entries;
634            }
635    
636            @Override
637            public String getFileEntryImage(
638                    FileEntry fileEntry, ThemeDisplay themeDisplay) {
639    
640                    StringBundler sb = new StringBundler(5);
641    
642                    sb.append("<img style=\"border-width: 0; text-align: left;\" src=\"");
643                    sb.append(themeDisplay.getPathThemeImages());
644                    sb.append("/file_system/small/");
645                    sb.append(fileEntry.getIcon());
646                    sb.append(".png\">");
647    
648                    return sb.toString();
649            }
650    
651            @Override
652            public Set<Long> getFileEntryTypeSubscriptionClassPKs(long userId)
653                    throws SystemException {
654    
655                    List<Subscription> subscriptions =
656                            SubscriptionLocalServiceUtil.getUserSubscriptions(
657                                    userId, DLFileEntryType.class.getName());
658    
659                    Set<Long> classPKs = new HashSet<Long>(subscriptions.size());
660    
661                    for (Subscription subscription : subscriptions) {
662                            classPKs.add(subscription.getClassPK());
663                    }
664    
665                    return classPKs;
666            }
667    
668            @Override
669            public String getFileIcon(String extension) {
670                    if (!_fileIcons.contains(extension)) {
671                            extension = _DEFAULT_FILE_ICON;
672                    }
673    
674                    return extension;
675            }
676    
677            @Override
678            public String getGenericName(String extension) {
679                    String genericName = _genericNames.get(extension);
680    
681                    if (genericName == null) {
682                            genericName = _DEFAULT_GENERIC_NAME;
683                    }
684    
685                    return genericName;
686            }
687    
688            @Override
689            public String getImagePreviewURL(
690                            FileEntry fileEntry, FileVersion fileVersion,
691                            ThemeDisplay themeDisplay)
692                    throws Exception {
693    
694                    String previewQueryString = null;
695    
696                    if (PropsValues.DL_FILE_ENTRY_THUMBNAIL_ENABLED) {
697                            if (ImageProcessorUtil.hasImages(fileVersion)) {
698                                    previewQueryString = "&imagePreview=1";
699                            }
700                            else if (PDFProcessorUtil.hasImages(fileVersion)) {
701                                    previewQueryString = "&previewFileIndex=1";
702                            }
703                            else if (VideoProcessorUtil.hasVideo(fileVersion)) {
704                                    previewQueryString = "&videoThumbnail=1";
705                            }
706                    }
707    
708                    return getImageSrc(
709                            fileEntry, fileVersion, themeDisplay, previewQueryString);
710            }
711    
712            @Override
713            public String getImagePreviewURL(
714                            FileEntry fileEntry, ThemeDisplay themeDisplay)
715                    throws Exception {
716    
717                    return getImagePreviewURL(
718                            fileEntry, fileEntry.getFileVersion(), themeDisplay);
719            }
720    
721            @Override
722            public String[] getMediaGalleryMimeTypes(
723                    PortletPreferences portletPreferences, PortletRequest portletRequest) {
724    
725                    String mimeTypes = PrefsParamUtil.getString(
726                            portletPreferences, portletRequest, "mimeTypes",
727                            _allMediaGalleryMimeTypesString);
728    
729                    String[] mimeTypesArray = StringUtil.split(mimeTypes);
730    
731                    Arrays.sort(mimeTypesArray);
732    
733                    return mimeTypesArray;
734            }
735    
736            @Override
737            public String getPreviewURL(
738                    FileEntry fileEntry, FileVersion fileVersion, ThemeDisplay themeDisplay,
739                    String queryString) {
740    
741                    return getPreviewURL(
742                            fileEntry, fileVersion, themeDisplay, queryString, true, true);
743            }
744    
745            /**
746             * @deprecated As of 6.2.0, replaced by {@link #getPreviewURL(FileEntry,
747             *             FileVersion, ThemeDisplay, String, boolean, boolean)}
748             */
749            @Override
750            public String getPreviewURL(
751                    FileEntry fileEntry, FileVersion fileVersion, ThemeDisplay themeDisplay,
752                    String queryString, boolean appendToken) {
753    
754                    return getPreviewURL(
755                            fileEntry, fileVersion, themeDisplay, queryString, true, true);
756            }
757    
758            @Override
759            public String getPreviewURL(
760                    FileEntry fileEntry, FileVersion fileVersion, ThemeDisplay themeDisplay,
761                    String queryString, boolean appendVersion, boolean absoluteURL) {
762    
763                    StringBundler sb = new StringBundler(17);
764    
765                    if (themeDisplay != null) {
766                            if (absoluteURL) {
767                                    sb.append(themeDisplay.getPortalURL());
768                            }
769                    }
770    
771                    sb.append(PortalUtil.getPathContext());
772                    sb.append("/documents/");
773                    sb.append(fileEntry.getRepositoryId());
774                    sb.append(StringPool.SLASH);
775                    sb.append(fileEntry.getFolderId());
776                    sb.append(StringPool.SLASH);
777    
778                    String title = fileEntry.getTitle();
779    
780                    if (fileEntry.isInTrash()) {
781                            title = TrashUtil.getOriginalTitle(fileEntry.getTitle());
782                    }
783    
784                    sb.append(HttpUtil.encodeURL(HtmlUtil.unescape(title)));
785    
786                    sb.append(StringPool.SLASH);
787                    sb.append(fileEntry.getUuid());
788    
789                    if (appendVersion) {
790                            sb.append("?version=");
791                            sb.append(fileVersion.getVersion());
792                    }
793    
794                    if (ImageProcessorUtil.isImageSupported(fileVersion)) {
795                            if (appendVersion) {
796                                    sb.append("&t=");
797                            }
798                            else {
799                                    sb.append("?t=");
800                            }
801    
802                            Date modifiedDate = fileVersion.getModifiedDate();
803    
804                            sb.append(modifiedDate.getTime());
805                    }
806    
807                    sb.append(queryString);
808    
809                    if (themeDisplay != null) {
810                            PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
811    
812                            if (portletDisplay != null) {
813                                    String portletId = portletDisplay.getId();
814    
815                                    if (portletId.equals(PortletKeys.TRASH)) {
816                                            sb.append("&status=");
817                                            sb.append(WorkflowConstants.STATUS_IN_TRASH);
818                                    }
819                            }
820                    }
821    
822                    String previewURL = sb.toString();
823    
824                    if ((themeDisplay != null) && themeDisplay.isAddSessionIdToURL()) {
825                            return PortalUtil.getURLWithSessionId(
826                                    previewURL, themeDisplay.getSessionId());
827                    }
828    
829                    return previewURL;
830            }
831    
832            @Override
833            public OrderByComparator getRepositoryModelOrderByComparator(
834                    String orderByCol, String orderByType) {
835    
836                    boolean orderByAsc = true;
837    
838                    if (orderByType.equals("desc")) {
839                            orderByAsc = false;
840                    }
841    
842                    OrderByComparator orderByComparator = null;
843    
844                    if (orderByCol.equals("creationDate")) {
845                            orderByComparator = new RepositoryModelCreateDateComparator(
846                                    orderByAsc);
847                    }
848                    else if (orderByCol.equals("downloads")) {
849                            orderByComparator = new RepositoryModelReadCountComparator(
850                                    orderByAsc);
851                    }
852                    else if (orderByCol.equals("modifiedDate")) {
853                            orderByComparator = new RepositoryModelModifiedDateComparator(
854                                    orderByAsc);
855                    }
856                    else if (orderByCol.equals("size")) {
857                            orderByComparator = new RepositoryModelSizeComparator(orderByAsc);
858                    }
859                    else {
860                            orderByComparator = new RepositoryModelNameComparator(orderByAsc);
861                    }
862    
863                    return orderByComparator;
864            }
865    
866            @Override
867            public String getTempFileId(long id, String version) {
868                    return getTempFileId(id, version, null);
869            }
870    
871            @Override
872            public String getTempFileId(long id, String version, String languageId) {
873                    if (Validator.isNull(languageId)) {
874                            return String.valueOf(id).concat(StringPool.PERIOD).concat(version);
875                    }
876    
877                    StringBundler sb = new StringBundler(5);
878    
879                    sb.append(id);
880                    sb.append(StringPool.PERIOD);
881                    sb.append(version);
882                    sb.append(StringPool.PERIOD);
883                    sb.append(languageId);
884    
885                    return sb.toString();
886            }
887    
888            @Override
889            public String getThumbnailSrc(
890                            FileEntry fileEntry, DLFileShortcut dlFileShortcut,
891                            ThemeDisplay themeDisplay)
892                    throws Exception {
893    
894                    return getThumbnailSrc(
895                            fileEntry, fileEntry.getFileVersion(), dlFileShortcut,
896                            themeDisplay);
897            }
898    
899            @Override
900            public String getThumbnailSrc(
901                            FileEntry fileEntry, FileVersion fileVersion,
902                            DLFileShortcut dlFileShortcut, ThemeDisplay themeDisplay)
903                    throws Exception {
904    
905                    String thumbnailQueryString = null;
906    
907                    if (PropsValues.DL_FILE_ENTRY_THUMBNAIL_ENABLED) {
908                            if (ImageProcessorUtil.hasImages(fileVersion)) {
909                                    thumbnailQueryString = "&imageThumbnail=1";
910                            }
911                            else if (PDFProcessorUtil.hasImages(fileVersion)) {
912                                    thumbnailQueryString = "&documentThumbnail=1";
913                            }
914                            else if (VideoProcessorUtil.hasVideo(fileVersion)) {
915                                    thumbnailQueryString = "&videoThumbnail=1";
916                            }
917                    }
918    
919                    return getImageSrc(
920                            fileEntry, fileVersion, themeDisplay, thumbnailQueryString);
921            }
922    
923            @Override
924            public String getThumbnailStyle() throws Exception {
925                    return getThumbnailStyle(true, 0);
926            }
927    
928            @Override
929            public String getThumbnailStyle(boolean max, int margin) throws Exception {
930                    StringBundler sb = new StringBundler(5);
931    
932                    if (max) {
933                            sb.append("max-height: ");
934                    }
935                    else {
936                            sb.append("height: ");
937                    }
938    
939                    sb.append(
940                            PrefsPropsUtil.getLong(
941                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_HEIGHT) + 2 * margin);
942    
943                    if (max) {
944                            sb.append("px; max-width: ");
945                    }
946                    else {
947                            sb.append("px; width: ");
948                    }
949    
950                    sb.append(
951                            PrefsPropsUtil.getLong(
952                                    PropsKeys.DL_FILE_ENTRY_THUMBNAIL_MAX_WIDTH) + 2 * margin);
953                    sb.append("px;");
954    
955                    return sb.toString();
956            }
957    
958            @Override
959            public String getTitleWithExtension(FileEntry fileEntry) {
960                    String title = fileEntry.getTitle();
961                    String extension = fileEntry.getExtension();
962    
963                    return getTitleWithExtension(title, extension);
964            }
965    
966            @Override
967            public String getTitleWithExtension(String title, String extension) {
968                    if (Validator.isNotNull(extension)) {
969                            String periodAndExtension = StringPool.PERIOD.concat(extension);
970    
971                            if (!title.endsWith(periodAndExtension)) {
972                                    title += periodAndExtension;
973                            }
974                    }
975    
976                    return title;
977            }
978    
979            @Override
980            public String getWebDavURL(
981                            ThemeDisplay themeDisplay, Folder folder, FileEntry fileEntry)
982                    throws PortalException, SystemException {
983    
984                    return getWebDavURL(themeDisplay, folder, fileEntry, false);
985            }
986    
987            @Override
988            public String getWebDavURL(
989                            ThemeDisplay themeDisplay, Folder folder, FileEntry fileEntry,
990                            boolean manualCheckInRequired)
991                    throws PortalException, SystemException {
992    
993                    return getWebDavURL(
994                            themeDisplay, folder, fileEntry, manualCheckInRequired, false);
995            }
996    
997            @Override
998            public String getWebDavURL(
999                            ThemeDisplay themeDisplay, Folder folder, FileEntry fileEntry,
1000                            boolean manualCheckInRequired, boolean openDocumentUrl)
1001                    throws PortalException, SystemException {
1002    
1003                    StringBundler webDavURL = new StringBundler(8);
1004    
1005                    boolean secure = false;
1006    
1007                    if (themeDisplay.isSecure() ||
1008                            PropsValues.WEBDAV_SERVLET_HTTPS_REQUIRED) {
1009    
1010                            secure = true;
1011                    }
1012    
1013                    String portalURL = PortalUtil.getPortalURL(
1014                            themeDisplay.getServerName(), themeDisplay.getServerPort(), secure);
1015    
1016                    webDavURL.append(portalURL);
1017    
1018                    webDavURL.append(themeDisplay.getPathContext());
1019                    webDavURL.append("/webdav");
1020    
1021                    if (manualCheckInRequired) {
1022                            webDavURL.append(MANUAL_CHECK_IN_REQUIRED_PATH);
1023                    }
1024    
1025                    String fileEntryTitle = null;
1026    
1027                    if (fileEntry != null) {
1028                            String extension = fileEntry.getExtension();
1029    
1030                            fileEntryTitle = HtmlUtil.unescape(fileEntry.getTitle());
1031    
1032                            if (openDocumentUrl && isOfficeExtension(extension) &&
1033                                    !fileEntryTitle.endsWith(StringPool.PERIOD + extension)) {
1034    
1035                                    webDavURL.append(OFFICE_EXTENSION_PATH);
1036    
1037                                    fileEntryTitle += StringPool.PERIOD + extension;
1038                            }
1039                    }
1040    
1041                    Group group = themeDisplay.getScopeGroup();
1042    
1043                    webDavURL.append(group.getFriendlyURL());
1044                    webDavURL.append("/document_library");
1045    
1046                    StringBuilder sb = new StringBuilder();
1047    
1048                    if ((folder != null) &&
1049                            (folder.getFolderId() !=
1050                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID)) {
1051    
1052                            Folder curFolder = folder;
1053    
1054                            while (true) {
1055                                    sb.insert(0, HttpUtil.encodeURL(curFolder.getName(), true));
1056                                    sb.insert(0, StringPool.SLASH);
1057    
1058                                    if (curFolder.getParentFolderId() ==
1059                                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1060    
1061                                            break;
1062                                    }
1063    
1064                                    curFolder = DLAppLocalServiceUtil.getFolder(
1065                                            curFolder.getParentFolderId());
1066                            }
1067                    }
1068    
1069                    if (fileEntry != null) {
1070                            sb.append(StringPool.SLASH);
1071                            sb.append(HttpUtil.encodeURL(fileEntryTitle, true));
1072                    }
1073    
1074                    webDavURL.append(sb.toString());
1075    
1076                    return webDavURL.toString();
1077            }
1078    
1079            @Override
1080            public boolean hasWorkflowDefinitionLink(
1081                            long companyId, long groupId, long folderId, long fileEntryTypeId)
1082                    throws Exception {
1083    
1084                    while (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1085                            DLFolder dlFolder = DLFolderLocalServiceUtil.fetchDLFolder(
1086                                    folderId);
1087    
1088                            if (dlFolder == null) {
1089                                    return false;
1090                            }
1091    
1092                            if (dlFolder.isOverrideFileEntryTypes()) {
1093                                    break;
1094                            }
1095    
1096                            folderId = dlFolder.getParentFolderId();
1097                    }
1098    
1099                    if (WorkflowDefinitionLinkLocalServiceUtil.hasWorkflowDefinitionLink(
1100                                    companyId, groupId, DLFolderConstants.getClassName(), folderId,
1101                                    fileEntryTypeId) ||
1102                            WorkflowDefinitionLinkLocalServiceUtil.hasWorkflowDefinitionLink(
1103                                    companyId, groupId, DLFolderConstants.getClassName(), folderId,
1104                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_ALL)) {
1105    
1106                            return true;
1107                    }
1108    
1109                    return false;
1110            }
1111    
1112            @Override
1113            public boolean isAutoGeneratedDLFileEntryTypeDDMStructureKey(
1114                    String ddmStructureKey) {
1115    
1116                    if (ddmStructureKey.startsWith(_STRUCTURE_KEY_PREFIX)) {
1117                            return true;
1118                    }
1119    
1120                    return false;
1121            }
1122    
1123            @Override
1124            public boolean isOfficeExtension(String extension) {
1125                    if (StringUtil.equalsIgnoreCase(extension, "doc") ||
1126                            StringUtil.equalsIgnoreCase(extension, "docx") ||
1127                            StringUtil.equalsIgnoreCase(extension, "dot") ||
1128                            StringUtil.equalsIgnoreCase(extension, "ppt") ||
1129                            StringUtil.equalsIgnoreCase(extension, "pptx") ||
1130                            StringUtil.equalsIgnoreCase(extension, "xls") ||
1131                            StringUtil.equalsIgnoreCase(extension, "xlsx")) {
1132    
1133                            return true;
1134                    }
1135    
1136                    return false;
1137            }
1138    
1139            @Override
1140            public boolean isSubscribedToFileEntryType(
1141                            long companyId, long groupId, long userId, long fileEntryTypeId)
1142                    throws SystemException {
1143    
1144                    if (fileEntryTypeId ==
1145                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
1146    
1147                            fileEntryTypeId = groupId;
1148                    }
1149    
1150                    return SubscriptionLocalServiceUtil.isSubscribed(
1151                            companyId, userId, DLFileEntryType.class.getName(),
1152                            fileEntryTypeId);
1153            }
1154    
1155            @Override
1156            public boolean isSubscribedToFolder(
1157                            long companyId, long groupId, long userId, long folderId)
1158                    throws PortalException, SystemException {
1159    
1160                    return isSubscribedToFolder(companyId, groupId, userId, folderId, true);
1161            }
1162    
1163            @Override
1164            public boolean isSubscribedToFolder(
1165                            long companyId, long groupId, long userId, long folderId,
1166                            boolean recursive)
1167                    throws PortalException, SystemException {
1168    
1169                    List<Long> ancestorFolderIds = new ArrayList<Long>();
1170    
1171                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1172                            Folder folder = DLAppLocalServiceUtil.getFolder(folderId);
1173    
1174                            if (recursive) {
1175                                    ancestorFolderIds = folder.getAncestorFolderIds();
1176    
1177                                    ancestorFolderIds.add(groupId);
1178                            }
1179    
1180                            ancestorFolderIds.add(0, folderId);
1181                    }
1182                    else {
1183                            ancestorFolderIds.add(groupId);
1184                    }
1185    
1186                    long[] folderIdsArray = ArrayUtil.toLongArray(ancestorFolderIds);
1187    
1188                    return SubscriptionLocalServiceUtil.isSubscribed(
1189                            companyId, userId, Folder.class.getName(), folderIdsArray);
1190            }
1191    
1192            protected long getDefaultFolderId(HttpServletRequest request)
1193                    throws Exception {
1194    
1195                    PortletPreferences portletPreferences =
1196                            PortletPreferencesFactoryUtil.getPortletPreferences(
1197                                    request, PortalUtil.getPortletId(request));
1198    
1199                    return GetterUtil.getLong(
1200                            portletPreferences.getValue(
1201                                    "rootFolderId",
1202                                    String.valueOf(DLFolderConstants.DEFAULT_PARENT_FOLDER_ID)));
1203            }
1204    
1205            protected String getImageSrc(
1206                            FileEntry fileEntry, FileVersion fileVersion,
1207                            ThemeDisplay themeDisplay, String queryString)
1208                    throws Exception {
1209    
1210                    StringBundler sb = new StringBundler(4);
1211    
1212                    sb.append(themeDisplay.getPathThemeImages());
1213                    sb.append("/file_system/large/");
1214                    sb.append(getGenericName(fileEntry.getExtension()));
1215                    sb.append(".png");
1216    
1217                    String thumbnailSrc = sb.toString();
1218    
1219                    if (Validator.isNotNull(queryString)) {
1220                            thumbnailSrc = getPreviewURL(
1221                                    fileEntry, fileVersion, themeDisplay, queryString, true, true);
1222                    }
1223    
1224                    return thumbnailSrc;
1225            }
1226    
1227            private static void _populateGenericNamesMap(String genericName) {
1228                    String[] extensions = PropsUtil.getArray(
1229                            PropsKeys.DL_FILE_GENERIC_EXTENSIONS, new Filter(genericName));
1230    
1231                    for (String extension : extensions) {
1232                            _genericNames.put(extension, genericName);
1233                    }
1234            }
1235    
1236            private static final String _DEFAULT_FILE_ICON = "page";
1237    
1238            private static final String _DEFAULT_GENERIC_NAME = "default";
1239    
1240            private static final long _DIVISOR = 256;
1241    
1242            private static final String _STRUCTURE_KEY_PREFIX = "AUTO_";
1243    
1244            private static Log _log = LogFactoryUtil.getLog(DLImpl.class);
1245    
1246            private static Set<String> _allMediaGalleryMimeTypes =
1247                    new TreeSet<String>();
1248            private static String _allMediaGalleryMimeTypesString;
1249            private static Set<String> _fileIcons = new HashSet<String>();
1250            private static Map<String, String> _genericNames =
1251                    new HashMap<String, String>();
1252    
1253            static {
1254                    _allMediaGalleryMimeTypes.addAll(
1255                            SetUtil.fromArray(
1256                                    PropsUtil.getArray(
1257                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_AUDIO_MIME_TYPES)));
1258                    _allMediaGalleryMimeTypes.addAll(
1259                            SetUtil.fromArray(
1260                                    PropsUtil.getArray(
1261                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO_MIME_TYPES)));
1262                    _allMediaGalleryMimeTypes.addAll(
1263                            SetUtil.fromArray(
1264                                    PropsUtil.getArray(
1265                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_IMAGE_MIME_TYPES)));
1266    
1267                    _allMediaGalleryMimeTypesString = StringUtil.merge(
1268                            _allMediaGalleryMimeTypes);
1269    
1270                    String[] fileIcons = null;
1271    
1272                    try {
1273                            fileIcons = PropsUtil.getArray(PropsKeys.DL_FILE_ICONS);
1274                    }
1275                    catch (Exception e) {
1276                            if (_log.isDebugEnabled()) {
1277                                    _log.debug(e, e);
1278                            }
1279    
1280                            fileIcons = new String[] {StringPool.BLANK};
1281                    }
1282    
1283                    for (int i = 0; i < fileIcons.length; i++) {
1284    
1285                            // Only process non wildcard extensions
1286    
1287                            if (!StringPool.STAR.equals(fileIcons[i])) {
1288    
1289                                    // Strip starting period
1290    
1291                                    String extension = fileIcons[i];
1292    
1293                                    if (extension.length() > 0) {
1294                                            extension = extension.substring(1);
1295                                    }
1296    
1297                                    _fileIcons.add(extension);
1298                            }
1299                    }
1300    
1301                    String[] genericNames = PropsUtil.getArray(
1302                            PropsKeys.DL_FILE_GENERIC_NAMES);
1303    
1304                    for (String genericName : genericNames) {
1305                            _populateGenericNamesMap(genericName);
1306                    }
1307            }
1308    
1309    }