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