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