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.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            public Group disableTrash(Group group) throws SystemException {
177                    UnicodeProperties typeSettingsProperties =
178                            group.getParentLiveGroupTypeSettingsProperties();
179    
180                    typeSettingsProperties.setProperty("trashEnabled", StringPool.FALSE);
181    
182                    group.setTypeSettingsProperties(typeSettingsProperties);
183    
184                    return GroupLocalServiceUtil.updateGroup(group);
185            }
186    
187            @Override
188            public List<TrashEntry> getEntries(Hits hits) {
189                    List<TrashEntry> entries = new ArrayList<TrashEntry>();
190    
191                    for (Document document : hits.getDocs()) {
192                            String entryClassName = GetterUtil.getString(
193                                    document.get(Field.ENTRY_CLASS_NAME));
194                            long classPK = GetterUtil.getLong(
195                                    document.get(Field.ENTRY_CLASS_PK));
196    
197                            try {
198                                    TrashEntry entry = TrashEntryLocalServiceUtil.fetchEntry(
199                                            entryClassName, classPK);
200    
201                                    if (entry == null) {
202                                            String userName = GetterUtil.getString(
203                                                    document.get(Field.REMOVED_BY_USER_NAME));
204    
205                                            Date removedDate = document.getDate(Field.REMOVED_DATE);
206    
207                                            entry = new TrashEntryImpl();
208    
209                                            entry.setClassName(entryClassName);
210                                            entry.setClassPK(classPK);
211    
212                                            entry.setUserName(userName);
213                                            entry.setCreateDate(removedDate);
214    
215                                            String rootEntryClassName = GetterUtil.getString(
216                                                    document.get(Field.ROOT_ENTRY_CLASS_NAME));
217                                            long rootEntryClassPK = GetterUtil.getLong(
218                                                    document.get(Field.ROOT_ENTRY_CLASS_PK));
219    
220                                            TrashEntry rootTrashEntry =
221                                                    TrashEntryLocalServiceUtil.fetchEntry(
222                                                            rootEntryClassName, rootEntryClassPK);
223    
224                                            if (rootTrashEntry != null) {
225                                                    entry.setRootEntry(rootTrashEntry);
226                                            }
227                                    }
228    
229                                    entries.add(entry);
230                            }
231                            catch (Exception e) {
232                                    if (_log.isWarnEnabled()) {
233                                            _log.warn(
234                                                    "Unable to find trash entry for " + entryClassName +
235                                                            " with primary key " + classPK);
236                                    }
237                            }
238                    }
239    
240                    return entries;
241            }
242    
243            @Override
244            public OrderByComparator getEntryOrderByComparator(
245                    String orderByCol, String orderByType) {
246    
247                    boolean orderByAsc = false;
248    
249                    if (orderByType.equals("asc")) {
250                            orderByAsc = true;
251                    }
252    
253                    OrderByComparator orderByComparator = null;
254    
255                    if (orderByCol.equals("removed-by")) {
256                            orderByComparator = new EntryUserNameComparator(orderByAsc);
257                    }
258                    else if (orderByCol.equals("removed-date")) {
259                            orderByComparator = new EntryCreateDateComparator(orderByAsc);
260                    }
261                    else if (orderByCol.equals("type")) {
262                            orderByComparator = new EntryTypeComparator(orderByAsc);
263                    }
264    
265                    return orderByComparator;
266            }
267    
268            @Override
269            public int getMaxAge(Group group) throws PortalException, SystemException {
270                    if (group.isLayout()) {
271                            group = group.getParentGroup();
272                    }
273    
274                    int trashEntriesMaxAge = PrefsPropsUtil.getInteger(
275                            group.getCompanyId(), PropsKeys.TRASH_ENTRIES_MAX_AGE,
276                            PropsValues.TRASH_ENTRIES_MAX_AGE);
277    
278                    UnicodeProperties typeSettingsProperties =
279                            group.getTypeSettingsProperties();
280    
281                    return GetterUtil.getInteger(
282                            typeSettingsProperties.getProperty("trashEntriesMaxAge"),
283                            trashEntriesMaxAge);
284            }
285    
286            @Override
287            public String getNewName(String oldName, String token) {
288                    StringBundler sb = new StringBundler(3);
289    
290                    sb.append(oldName);
291                    sb.append(StringPool.SPACE);
292                    sb.append(token);
293    
294                    return sb.toString();
295            }
296    
297            @Override
298            public String getNewName(
299                            ThemeDisplay themeDisplay, String className, long classPK,
300                            String oldName)
301                    throws PortalException, SystemException {
302    
303                    TrashRenderer trashRenderer = null;
304    
305                    if (Validator.isNotNull(className) && (classPK > 0)) {
306                            TrashHandler trashHandler =
307                                    TrashHandlerRegistryUtil.getTrashHandler(className);
308    
309                            trashRenderer = trashHandler.getTrashRenderer(classPK);
310                    }
311    
312                    Format dateFormatDateTime = FastDateFormatFactoryUtil.getDateTime(
313                            themeDisplay.getLocale(), themeDisplay.getTimeZone());
314    
315                    StringBundler sb = new StringBundler(3);
316    
317                    sb.append(StringPool.OPEN_PARENTHESIS);
318                    sb.append(
319                            StringUtil.replace(
320                                    dateFormatDateTime.format(new Date()), CharPool.SLASH,
321                                    CharPool.PERIOD));
322                    sb.append(StringPool.CLOSE_PARENTHESIS);
323    
324                    if (trashRenderer != null) {
325                            return trashRenderer.getNewName(oldName, sb.toString());
326                    }
327                    else {
328                            return getNewName(oldName, sb.toString());
329                    }
330            }
331    
332            @Override
333            public String getOriginalTitle(String title) {
334                    return getOriginalTitle(title, StringPool.SLASH);
335            }
336    
337            @Override
338            public String getTrashTime(String title, String separator) {
339                    int index = title.lastIndexOf(separator);
340    
341                    if (index < 0) {
342                            return StringPool.BLANK;
343                    }
344    
345                    return title.substring(index + 1, title.length());
346            }
347    
348            @Override
349            public String getTrashTitle(long trashEntryId) {
350                    return getTrashTitle(trashEntryId, StringPool.SLASH);
351            }
352    
353            @Override
354            public PortletURL getViewContentURL(
355                            HttpServletRequest request, String className, long classPK)
356                    throws PortalException, SystemException {
357    
358                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
359                            WebKeys.THEME_DISPLAY);
360    
361                    if (!themeDisplay.isSignedIn() ||
362                            !isTrashEnabled(themeDisplay.getScopeGroupId()) ||
363                            !PortletPermissionUtil.hasControlPanelAccessPermission(
364                                    themeDisplay.getPermissionChecker(),
365                                    themeDisplay.getScopeGroupId(), PortletKeys.TRASH)) {
366    
367                            return null;
368                    }
369    
370                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
371                            className);
372    
373                    if (trashHandler.isInTrashContainer(classPK)) {
374                            TrashEntry trashEntry = trashHandler.getTrashEntry(classPK);
375    
376                            className = trashEntry.getClassName();
377                            classPK = trashEntry.getClassPK();
378    
379                            trashHandler = TrashHandlerRegistryUtil.getTrashHandler(className);
380                    }
381    
382                    TrashRenderer trashRenderer = trashHandler.getTrashRenderer(classPK);
383    
384                    if (trashRenderer == null) {
385                            return null;
386                    }
387    
388                    Layout layout = themeDisplay.getLayout();
389    
390                    PortletURL portletURL = PortalUtil.getControlPanelPortletURL(
391                            request, PortletKeys.TRASH, layout.getLayoutId(),
392                            PortletRequest.RENDER_PHASE);
393    
394                    portletURL.setParameter("struts_action", "/trash/view_content");
395                    portletURL.setParameter("redirect", themeDisplay.getURLCurrent());
396    
397                    TrashEntry trashEntry = TrashEntryLocalServiceUtil.getEntry(
398                            className, classPK);
399    
400                    if (trashEntry.getRootEntry() != null) {
401                            portletURL.setParameter("className", className);
402                            portletURL.setParameter("classPK", String.valueOf(classPK));
403                    }
404                    else {
405                            portletURL.setParameter(
406                                    "trashEntryId", String.valueOf(trashEntry.getEntryId()));
407                    }
408    
409                    portletURL.setParameter("type", trashRenderer.getType());
410                    portletURL.setParameter("showActions", Boolean.FALSE.toString());
411                    portletURL.setParameter("showAssetMetadata", Boolean.TRUE.toString());
412                    portletURL.setParameter("showEditURL", Boolean.FALSE.toString());
413    
414                    return portletURL;
415            }
416    
417            @Override
418            public boolean isInTrash(String className, long classPK)
419                    throws PortalException, SystemException {
420    
421                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
422                            className);
423    
424                    if (trashHandler == null) {
425                            return false;
426                    }
427    
428                    return trashHandler.isInTrash(classPK);
429            }
430    
431            @Override
432            public boolean isTrashEnabled(long groupId)
433                    throws PortalException, SystemException {
434    
435                    Group group = GroupLocalServiceUtil.getGroup(groupId);
436    
437                    UnicodeProperties typeSettingsProperties =
438                            group.getParentLiveGroupTypeSettingsProperties();
439    
440                    boolean companyTrashEnabled = PrefsPropsUtil.getBoolean(
441                            group.getCompanyId(), PropsKeys.TRASH_ENABLED);
442    
443                    if (!companyTrashEnabled) {
444                            return false;
445                    }
446    
447                    return GetterUtil.getBoolean(
448                            typeSettingsProperties.getProperty("trashEnabled"), true);
449            }
450    
451            /**
452             * @deprecated As of 7.0.0, replaced by {@link
453             *             #addBreadcrumbEntries(HttpServletRequest,
454             *             LiferayPortletResponse, String, long, String, PortletURL}
455             */
456            @Deprecated
457            protected void addBreadcrumbEntries(
458                            HttpServletRequest request, String className, long classPK,
459                            String paramName, PortletURL containerModelURL)
460                    throws PortalException, SystemException {
461    
462                    addBreadcrumbEntries(
463                            request, null, className, classPK, paramName, containerModelURL);
464            }
465    
466            protected void addBreadcrumbEntries(
467                            HttpServletRequest request,
468                            LiferayPortletResponse liferayPortletResponse, String className,
469                            long classPK, String paramName, PortletURL containerModelURL)
470                    throws PortalException, SystemException {
471    
472                    PortletURL portletURL = null;
473    
474                    try {
475                            portletURL = PortletURLUtil.clone(
476                                    containerModelURL, liferayPortletResponse);
477                    }
478                    catch (PortletException ple) {
479                            throw new PortalException(ple);
480                    }
481    
482                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
483                            WebKeys.THEME_DISPLAY);
484    
485                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
486                            className);
487    
488                    List<ContainerModel> containerModels =
489                            trashHandler.getParentContainerModels(classPK);
490    
491                    Collections.reverse(containerModels);
492    
493                    portletURL.setParameter("struts_action", "/trash/view");
494    
495                    PortalUtil.addPortletBreadcrumbEntry(
496                            request, LanguageUtil.get(themeDisplay.getLocale(), "recycle-bin"),
497                            portletURL.toString());
498    
499                    for (ContainerModel containerModel : containerModels) {
500                            TrashHandler containerModelTrashHandler =
501                                    TrashHandlerRegistryUtil.getTrashHandler(
502                                            containerModel.getModelClassName());
503    
504                            if (!containerModelTrashHandler.isInTrash(
505                                            containerModel.getContainerModelId())) {
506    
507                                    continue;
508                            }
509    
510                            portletURL.setParameter("struts_action", "/trash/view_content");
511    
512                            portletURL.setParameter(
513                                    paramName,
514                                    String.valueOf(containerModel.getContainerModelId()));
515    
516                            String name = containerModel.getContainerModelName();
517    
518                            if (containerModelTrashHandler.isInTrash(
519                                            containerModel.getContainerModelId())) {
520    
521                                    name = TrashUtil.getOriginalTitle(name);
522                            }
523    
524                            PortalUtil.addPortletBreadcrumbEntry(
525                                    request, name, portletURL.toString());
526                    }
527    
528                    TrashRenderer trashRenderer = trashHandler.getTrashRenderer(classPK);
529    
530                    PortalUtil.addPortletBreadcrumbEntry(
531                            request, trashRenderer.getTitle(themeDisplay.getLocale()), null);
532            }
533    
534            protected String getOriginalTitle(String title, String prefix) {
535                    if (!title.startsWith(prefix)) {
536                            return title;
537                    }
538    
539                    title = title.substring(prefix.length());
540    
541                    long trashEntryId = GetterUtil.getLong(title);
542    
543                    if (trashEntryId <= 0) {
544                            return title;
545                    }
546    
547                    try {
548                            TrashEntry trashEntry = TrashEntryLocalServiceUtil.getEntry(
549                                    trashEntryId);
550    
551                            title = trashEntry.getTypeSettingsProperty("title");
552                    }
553                    catch (Exception e) {
554                            if (_log.isDebugEnabled()) {
555                                    _log.debug("No trash entry exists with ID " + trashEntryId);
556                            }
557                    }
558    
559                    return title;
560            }
561    
562            protected String getTrashTitle(long trashEntryId, String prefix) {
563                    return prefix.concat(String.valueOf(trashEntryId));
564            }
565    
566            private static Log _log = LogFactoryUtil.getLog(TrashImpl.class);
567    
568    }