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