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