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