001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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    /**
084     * @author Sergio Gonz??lez
085     * @author Julio Camarero
086     */
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    }