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