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.trash.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.language.LanguageUtil;
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.search.Document;
024    import com.liferay.portal.kernel.search.Field;
025    import com.liferay.portal.kernel.search.Hits;
026    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
027    import com.liferay.portal.kernel.trash.TrashHandler;
028    import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
029    import com.liferay.portal.kernel.trash.TrashRenderer;
030    import com.liferay.portal.kernel.util.CharPool;
031    import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
032    import com.liferay.portal.kernel.util.GetterUtil;
033    import com.liferay.portal.kernel.util.OrderByComparator;
034    import com.liferay.portal.kernel.util.PrefsPropsUtil;
035    import com.liferay.portal.kernel.util.PropsKeys;
036    import com.liferay.portal.kernel.util.StringBundler;
037    import com.liferay.portal.kernel.util.StringPool;
038    import com.liferay.portal.kernel.util.StringUtil;
039    import com.liferay.portal.kernel.util.UnicodeProperties;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.model.ContainerModel;
042    import com.liferay.portal.model.Group;
043    import com.liferay.portal.model.Layout;
044    import com.liferay.portal.service.GroupLocalServiceUtil;
045    import com.liferay.portal.service.permission.PortletPermissionUtil;
046    import com.liferay.portal.theme.ThemeDisplay;
047    import com.liferay.portal.util.PortalUtil;
048    import com.liferay.portal.util.PortletKeys;
049    import com.liferay.portal.util.PropsValues;
050    import com.liferay.portal.util.WebKeys;
051    import com.liferay.portlet.PortletURLUtil;
052    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
053    import com.liferay.portlet.trash.model.TrashEntry;
054    import com.liferay.portlet.trash.model.impl.TrashEntryImpl;
055    import com.liferay.portlet.trash.service.TrashEntryLocalServiceUtil;
056    import com.liferay.portlet.trash.util.comparator.EntryCreateDateComparator;
057    import com.liferay.portlet.trash.util.comparator.EntryTypeComparator;
058    import com.liferay.portlet.trash.util.comparator.EntryUserNameComparator;
059    
060    import java.text.Format;
061    
062    import java.util.ArrayList;
063    import java.util.Collections;
064    import java.util.Date;
065    import java.util.List;
066    
067    import javax.portlet.PortletException;
068    import javax.portlet.PortletRequest;
069    import javax.portlet.PortletURL;
070    
071    import javax.servlet.http.HttpServletRequest;
072    
073    /**
074     * @author Sergio Gonz??lez
075     * @author Julio Camarero
076     */
077    @DoPrivileged
078    public class TrashImpl implements Trash {
079    
080            @Override
081            public void addBaseModelBreadcrumbEntries(
082                            HttpServletRequest request,
083                            LiferayPortletResponse liferayPortletResponse, String className,
084                            long classPK, PortletURL containerModelURL)
085                    throws PortalException, SystemException {
086    
087                    addBreadcrumbEntries(
088                            request, liferayPortletResponse, className, classPK, "classPK",
089                            containerModelURL);
090            }
091    
092            /**
093             * @deprecated As of 7.0.0, replaced by {@link
094             *             #addBaseModelBreadcrumbEntries(HttpServletRequest,
095             *             LiferayPortletResponse, String, long, PortletURL}
096             */
097            @Deprecated
098            @Override
099            public void addBaseModelBreadcrumbEntries(
100                            HttpServletRequest request, String className, long classPK,
101                            PortletURL containerModelURL)
102                    throws PortalException, SystemException {
103    
104                    addBreadcrumbEntries(
105                            request, className, classPK, "classPK", containerModelURL);
106            }
107    
108            @Override
109            public void addContainerModelBreadcrumbEntries(
110                            HttpServletRequest request,
111                            LiferayPortletResponse liferayPortletResponse, String className,
112                            long classPK, PortletURL containerModelURL)
113                    throws PortalException, SystemException {
114    
115                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
116                            WebKeys.THEME_DISPLAY);
117    
118                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
119                            className);
120    
121                    String rootContainerModelName = LanguageUtil.get(
122                            themeDisplay.getLocale(), trashHandler.getRootContainerModelName());
123    
124                    if (classPK == 0) {
125                            PortalUtil.addPortletBreadcrumbEntry(
126                                    request, rootContainerModelName, null);
127    
128                            return;
129                    }
130    
131                    containerModelURL.setParameter("containerModelId", "0");
132    
133                    PortalUtil.addPortletBreadcrumbEntry(
134                            request, rootContainerModelName, containerModelURL.toString());
135    
136                    addBreadcrumbEntries(
137                            request, liferayPortletResponse, className, classPK,
138                            "containerModelId", containerModelURL);
139            }
140    
141            /**
142             * @deprecated As of 7.0.0, replaced by {@link
143             *             #addContainerModelBreadcrumbEntries(HttpServletRequest,
144             *             LiferayPortletResponse, String, long, PortletURL}
145             */
146            @Deprecated
147            @Override
148            public void addContainerModelBreadcrumbEntries(
149                            HttpServletRequest request, String className, long classPK,
150                            PortletURL containerModelURL)
151                    throws PortalException, SystemException {
152    
153                    addContainerModelBreadcrumbEntries(
154                            request, null, className, classPK, containerModelURL);
155            }
156    
157            @Override
158            public void deleteEntriesAttachments(
159                            long companyId, long repositoryId, Date date,
160                            String[] attachmentFileNames)
161                    throws PortalException, SystemException {
162    
163                    for (String attachmentFileName : attachmentFileNames) {
164                            String trashTime = TrashUtil.getTrashTime(
165                                    attachmentFileName, TRASH_TIME_SEPARATOR);
166    
167                            long timestamp = GetterUtil.getLong(trashTime);
168    
169                            if (timestamp < date.getTime()) {
170                                    DLStoreUtil.deleteDirectory(
171                                            companyId, repositoryId, attachmentFileName);
172                            }
173                    }
174            }
175    
176            @Override
177            public List<TrashEntry> getEntries(Hits hits) {
178                    List<TrashEntry> entries = new ArrayList<TrashEntry>();
179    
180                    for (Document document : hits.getDocs()) {
181                            String entryClassName = GetterUtil.getString(
182                                    document.get(Field.ENTRY_CLASS_NAME));
183                            long classPK = GetterUtil.getLong(
184                                    document.get(Field.ENTRY_CLASS_PK));
185    
186                            try {
187                                    TrashEntry entry = TrashEntryLocalServiceUtil.fetchEntry(
188                                            entryClassName, classPK);
189    
190                                    if (entry == null) {
191                                            String userName = GetterUtil.getString(
192                                                    document.get(Field.REMOVED_BY_USER_NAME));
193    
194                                            Date removedDate = document.getDate(Field.REMOVED_DATE);
195    
196                                            entry = new TrashEntryImpl();
197    
198                                            entry.setClassName(entryClassName);
199                                            entry.setClassPK(classPK);
200    
201                                            entry.setUserName(userName);
202                                            entry.setCreateDate(removedDate);
203    
204                                            String rootEntryClassName = GetterUtil.getString(
205                                                    document.get(Field.ROOT_ENTRY_CLASS_NAME));
206                                            long rootEntryClassPK = GetterUtil.getLong(
207                                                    document.get(Field.ROOT_ENTRY_CLASS_PK));
208    
209                                            TrashEntry rootTrashEntry =
210                                                    TrashEntryLocalServiceUtil.fetchEntry(
211                                                            rootEntryClassName, rootEntryClassPK);
212    
213                                            if (rootTrashEntry != null) {
214                                                    entry.setRootEntry(rootTrashEntry);
215                                            }
216                                    }
217    
218                                    entries.add(entry);
219                            }
220                            catch (Exception e) {
221                                    if (_log.isWarnEnabled()) {
222                                            _log.warn(
223                                                    "Unable to find trash entry for " + entryClassName +
224                                                            " with primary key " + classPK);
225                                    }
226                            }
227                    }
228    
229                    return entries;
230            }
231    
232            @Override
233            public OrderByComparator getEntryOrderByComparator(
234                    String orderByCol, String orderByType) {
235    
236                    boolean orderByAsc = false;
237    
238                    if (orderByType.equals("asc")) {
239                            orderByAsc = true;
240                    }
241    
242                    OrderByComparator orderByComparator = null;
243    
244                    if (orderByCol.equals("removed-by")) {
245                            orderByComparator = new EntryUserNameComparator(orderByAsc);
246                    }
247                    else if (orderByCol.equals("removed-date")) {
248                            orderByComparator = new EntryCreateDateComparator(orderByAsc);
249                    }
250                    else if (orderByCol.equals("type")) {
251                            orderByComparator = new EntryTypeComparator(orderByAsc);
252                    }
253    
254                    return orderByComparator;
255            }
256    
257            @Override
258            public int getMaxAge(Group group) throws PortalException, SystemException {
259                    if (group.isLayout()) {
260                            group = group.getParentGroup();
261                    }
262    
263                    int trashEntriesMaxAge = PrefsPropsUtil.getInteger(
264                            group.getCompanyId(), PropsKeys.TRASH_ENTRIES_MAX_AGE,
265                            PropsValues.TRASH_ENTRIES_MAX_AGE);
266    
267                    UnicodeProperties typeSettingsProperties =
268                            group.getTypeSettingsProperties();
269    
270                    return GetterUtil.getInteger(
271                            typeSettingsProperties.getProperty("trashEntriesMaxAge"),
272                            trashEntriesMaxAge);
273            }
274    
275            @Override
276            public String getNewName(String oldName, String token) {
277                    StringBundler sb = new StringBundler(3);
278    
279                    sb.append(oldName);
280                    sb.append(StringPool.SPACE);
281                    sb.append(token);
282    
283                    return sb.toString();
284            }
285    
286            @Override
287            public String getNewName(
288                            ThemeDisplay themeDisplay, String className, long classPK,
289                            String oldName)
290                    throws PortalException, SystemException {
291    
292                    TrashRenderer trashRenderer = null;
293    
294                    if (Validator.isNotNull(className) && (classPK > 0)) {
295                            TrashHandler trashHandler =
296                                    TrashHandlerRegistryUtil.getTrashHandler(className);
297    
298                            trashRenderer = trashHandler.getTrashRenderer(classPK);
299                    }
300    
301                    Format dateFormatDateTime = FastDateFormatFactoryUtil.getDateTime(
302                            themeDisplay.getLocale(), themeDisplay.getTimeZone());
303    
304                    StringBundler sb = new StringBundler(3);
305    
306                    sb.append(StringPool.OPEN_PARENTHESIS);
307                    sb.append(
308                            StringUtil.replace(
309                                    dateFormatDateTime.format(new Date()), CharPool.SLASH,
310                                    CharPool.PERIOD));
311                    sb.append(StringPool.CLOSE_PARENTHESIS);
312    
313                    if (trashRenderer != null) {
314                            return trashRenderer.getNewName(oldName, sb.toString());
315                    }
316                    else {
317                            return getNewName(oldName, sb.toString());
318                    }
319            }
320    
321            @Override
322            public String getOriginalTitle(String title) {
323                    return getOriginalTitle(title, StringPool.SLASH);
324            }
325    
326            @Override
327            public String getTrashTime(String title, String separator) {
328                    int index = title.lastIndexOf(separator);
329    
330                    if (index < 0) {
331                            return StringPool.BLANK;
332                    }
333    
334                    return title.substring(index + 1, title.length());
335            }
336    
337            @Override
338            public String getTrashTitle(long trashEntryId) {
339                    return getTrashTitle(trashEntryId, StringPool.SLASH);
340            }
341    
342            @Override
343            public PortletURL getViewContentURL(
344                            HttpServletRequest request, String className, long classPK)
345                    throws PortalException, SystemException {
346    
347                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
348                            WebKeys.THEME_DISPLAY);
349    
350                    if (!themeDisplay.isSignedIn() ||
351                            !isTrashEnabled(themeDisplay.getScopeGroupId()) ||
352                            !PortletPermissionUtil.hasControlPanelAccessPermission(
353                                    themeDisplay.getPermissionChecker(),
354                                    themeDisplay.getScopeGroupId(), PortletKeys.TRASH)) {
355    
356                            return null;
357                    }
358    
359                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
360                            className);
361    
362                    if (trashHandler.isInTrashContainer(classPK)) {
363                            TrashEntry trashEntry = trashHandler.getTrashEntry(classPK);
364    
365                            className = trashEntry.getClassName();
366                            classPK = trashEntry.getClassPK();
367    
368                            trashHandler = TrashHandlerRegistryUtil.getTrashHandler(className);
369                    }
370    
371                    TrashRenderer trashRenderer = trashHandler.getTrashRenderer(classPK);
372    
373                    if (trashRenderer == null) {
374                            return null;
375                    }
376    
377                    Layout layout = themeDisplay.getLayout();
378    
379                    PortletURL portletURL = PortalUtil.getControlPanelPortletURL(
380                            request, PortletKeys.TRASH, layout.getLayoutId(),
381                            PortletRequest.RENDER_PHASE);
382    
383                    portletURL.setParameter("struts_action", "/trash/view_content");
384                    portletURL.setParameter("redirect", themeDisplay.getURLCurrent());
385    
386                    TrashEntry trashEntry = TrashEntryLocalServiceUtil.getEntry(
387                            className, classPK);
388    
389                    if (trashEntry.getRootEntry() != null) {
390                            portletURL.setParameter("className", className);
391                            portletURL.setParameter("classPK", String.valueOf(classPK));
392                    }
393                    else {
394                            portletURL.setParameter(
395                                    "trashEntryId", String.valueOf(trashEntry.getEntryId()));
396                    }
397    
398                    portletURL.setParameter("type", trashRenderer.getType());
399                    portletURL.setParameter("showActions", Boolean.FALSE.toString());
400                    portletURL.setParameter("showAssetMetadata", Boolean.TRUE.toString());
401                    portletURL.setParameter("showEditURL", Boolean.FALSE.toString());
402    
403                    return portletURL;
404            }
405    
406            @Override
407            public boolean isInTrash(String className, long classPK)
408                    throws PortalException, SystemException {
409    
410                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
411                            className);
412    
413                    if (trashHandler == null) {
414                            return false;
415                    }
416    
417                    return trashHandler.isInTrash(classPK);
418            }
419    
420            @Override
421            public boolean isTrashEnabled(long groupId)
422                    throws PortalException, SystemException {
423    
424                    Group group = GroupLocalServiceUtil.getGroup(groupId);
425    
426                    UnicodeProperties typeSettingsProperties =
427                            group.getParentLiveGroupTypeSettingsProperties();
428    
429                    boolean companyTrashEnabled = PrefsPropsUtil.getBoolean(
430                            group.getCompanyId(), PropsKeys.TRASH_ENABLED);
431    
432                    if (!companyTrashEnabled) {
433                            return false;
434                    }
435    
436                    return GetterUtil.getBoolean(
437                            typeSettingsProperties.getProperty("trashEnabled"), true);
438            }
439    
440            /**
441             * @deprecated As of 7.0.0, replaced by {@link
442             *             #addBreadcrumbEntries(HttpServletRequest,
443             *             LiferayPortletResponse, String, long, String, PortletURL}
444             */
445            @Deprecated
446            protected void addBreadcrumbEntries(
447                            HttpServletRequest request, String className, long classPK,
448                            String paramName, PortletURL containerModelURL)
449                    throws PortalException, SystemException {
450    
451                    addBreadcrumbEntries(
452                            request, null, className, classPK, paramName, containerModelURL);
453            }
454    
455            protected void addBreadcrumbEntries(
456                            HttpServletRequest request,
457                            LiferayPortletResponse liferayPortletResponse, String className,
458                            long classPK, String paramName, PortletURL containerModelURL)
459                    throws PortalException, SystemException {
460    
461                    PortletURL portletURL = null;
462    
463                    try {
464                            portletURL = PortletURLUtil.clone(
465                                    containerModelURL, liferayPortletResponse);
466                    }
467                    catch (PortletException ple) {
468                            throw new PortalException(ple);
469                    }
470    
471                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
472                            WebKeys.THEME_DISPLAY);
473    
474                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
475                            className);
476    
477                    List<ContainerModel> containerModels =
478                            trashHandler.getParentContainerModels(classPK);
479    
480                    Collections.reverse(containerModels);
481    
482                    portletURL.setParameter("struts_action", "/trash/view");
483    
484                    PortalUtil.addPortletBreadcrumbEntry(
485                            request, LanguageUtil.get(themeDisplay.getLocale(), "recycle-bin"),
486                            portletURL.toString());
487    
488                    for (ContainerModel containerModel : containerModels) {
489                            TrashHandler containerModelTrashHandler =
490                                    TrashHandlerRegistryUtil.getTrashHandler(
491                                            containerModel.getModelClassName());
492    
493                            if (!containerModelTrashHandler.isInTrash(
494                                            containerModel.getContainerModelId())) {
495    
496                                    continue;
497                            }
498    
499                            portletURL.setParameter("struts_action", "/trash/view_content");
500    
501                            portletURL.setParameter(
502                                    paramName,
503                                    String.valueOf(containerModel.getContainerModelId()));
504    
505                            String name = containerModel.getContainerModelName();
506    
507                            if (containerModelTrashHandler.isInTrash(
508                                            containerModel.getContainerModelId())) {
509    
510                                    name = TrashUtil.getOriginalTitle(name);
511                            }
512    
513                            PortalUtil.addPortletBreadcrumbEntry(
514                                    request, name, portletURL.toString());
515                    }
516    
517                    TrashRenderer trashRenderer = trashHandler.getTrashRenderer(classPK);
518    
519                    PortalUtil.addPortletBreadcrumbEntry(
520                            request, trashRenderer.getTitle(themeDisplay.getLocale()), null);
521            }
522    
523            protected String getOriginalTitle(String title, String prefix) {
524                    if (!title.startsWith(prefix)) {
525                            return title;
526                    }
527    
528                    title = title.substring(prefix.length());
529    
530                    long trashEntryId = GetterUtil.getLong(title);
531    
532                    if (trashEntryId <= 0) {
533                            return title;
534                    }
535    
536                    try {
537                            TrashEntry trashEntry = TrashEntryLocalServiceUtil.getEntry(
538                                    trashEntryId);
539    
540                            title = trashEntry.getTypeSettingsProperty("title");
541                    }
542                    catch (Exception e) {
543                            if (_log.isDebugEnabled()) {
544                                    _log.debug("No trash entry exists with ID " + trashEntryId);
545                            }
546                    }
547    
548                    return title;
549            }
550    
551            protected String getTrashTitle(long trashEntryId, String prefix) {
552                    return prefix.concat(String.valueOf(trashEntryId));
553            }
554    
555            private static Log _log = LogFactoryUtil.getLog(TrashImpl.class);
556    
557    }