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.service.impl;
016    
017    import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DefaultActionableDynamicQuery;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.model.Group;
022    import com.liferay.portal.kernel.model.SystemEvent;
023    import com.liferay.portal.kernel.model.User;
024    import com.liferay.portal.kernel.search.BaseModelSearchResult;
025    import com.liferay.portal.kernel.search.Hits;
026    import com.liferay.portal.kernel.search.Indexable;
027    import com.liferay.portal.kernel.search.IndexableType;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
030    import com.liferay.portal.kernel.search.QueryConfig;
031    import com.liferay.portal.kernel.search.SearchContext;
032    import com.liferay.portal.kernel.search.Sort;
033    import com.liferay.portal.kernel.trash.TrashHandler;
034    import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
035    import com.liferay.portal.kernel.util.ObjectValuePair;
036    import com.liferay.portal.kernel.util.OrderByComparator;
037    import com.liferay.portal.kernel.util.UnicodeProperties;
038    import com.liferay.portlet.trash.service.base.TrashEntryLocalServiceBaseImpl;
039    import com.liferay.trash.kernel.model.TrashEntry;
040    import com.liferay.trash.kernel.model.TrashVersion;
041    import com.liferay.trash.kernel.util.TrashUtil;
042    
043    import java.util.Calendar;
044    import java.util.Date;
045    import java.util.List;
046    
047    /**
048     * Provides the local service for accessing, adding, checking, and deleting
049     * trash entries in the Recycle Bin.
050     *
051     * @author Zsolt Berentey
052     */
053    public class TrashEntryLocalServiceImpl extends TrashEntryLocalServiceBaseImpl {
054    
055            /**
056             * Moves an entry to trash.
057             *
058             * @param  userId the primary key of the user removing the entity
059             * @param  groupId the primary key of the entry's group
060             * @param  className the class name of the entity
061             * @param  classPK the primary key of the entity
062             * @param  classUuid the UUID of the entity's class
063             * @param  referrerClassName the referrer class name used to add a deletion
064             *         {@link SystemEvent}
065             * @param  status the status of the entity prior to being moved to trash
066             * @param  statusOVPs the primary keys and statuses of any of the entry's
067             *         versions (e.g., {@link
068             *         com.liferay.portlet.documentlibrary.model.DLFileVersion})
069             * @param  typeSettingsProperties the type settings properties
070             * @return the trashEntry
071             */
072            @Override
073            public TrashEntry addTrashEntry(
074                            long userId, long groupId, String className, long classPK,
075                            String classUuid, String referrerClassName, int status,
076                            List<ObjectValuePair<Long, Integer>> statusOVPs,
077                            UnicodeProperties typeSettingsProperties)
078                    throws PortalException {
079    
080                    User user = userPersistence.findByPrimaryKey(userId);
081                    long classNameId = classNameLocalService.getClassNameId(className);
082    
083                    TrashEntry trashEntry = trashEntryPersistence.fetchByC_C(
084                            classNameId, classPK);
085    
086                    if (trashEntry != null) {
087                            return trashEntry;
088                    }
089    
090                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
091                            className);
092    
093                    SystemEvent systemEvent = trashHandler.addDeletionSystemEvent(
094                            userId, groupId, classPK, classUuid, referrerClassName);
095    
096                    long entryId = counterLocalService.increment();
097    
098                    trashEntry = trashEntryPersistence.create(entryId);
099    
100                    trashEntry.setGroupId(groupId);
101                    trashEntry.setCompanyId(user.getCompanyId());
102                    trashEntry.setUserId(user.getUserId());
103                    trashEntry.setUserName(user.getFullName());
104                    trashEntry.setCreateDate(new Date());
105                    trashEntry.setClassNameId(classNameId);
106                    trashEntry.setClassPK(classPK);
107                    trashEntry.setSystemEventSetKey(systemEvent.getSystemEventSetKey());
108    
109                    if (typeSettingsProperties != null) {
110                            trashEntry.setTypeSettingsProperties(typeSettingsProperties);
111                    }
112    
113                    trashEntry.setStatus(status);
114    
115                    trashEntryPersistence.update(trashEntry);
116    
117                    if (statusOVPs != null) {
118                            for (ObjectValuePair<Long, Integer> statusOVP : statusOVPs) {
119                                    long versionId = counterLocalService.increment();
120    
121                                    TrashVersion trashVersion = trashVersionPersistence.create(
122                                            versionId);
123    
124                                    trashVersion.setEntryId(entryId);
125                                    trashVersion.setClassNameId(classNameId);
126                                    trashVersion.setClassPK(statusOVP.getKey());
127                                    trashVersion.setStatus(statusOVP.getValue());
128    
129                                    trashVersionPersistence.update(trashVersion);
130                            }
131                    }
132    
133                    return trashEntry;
134            }
135    
136            @Override
137            public void checkEntries() throws PortalException {
138                    ActionableDynamicQuery actionableDynamicQuery =
139                            trashEntryLocalService.getActionableDynamicQuery();
140    
141                    actionableDynamicQuery.setPerformActionMethod(
142                            new ActionableDynamicQuery.PerformActionMethod<TrashEntry>() {
143    
144                                    @Override
145                                    public void performAction(TrashEntry trashEntry)
146                                            throws PortalException {
147    
148                                            Date createDate = trashEntry.getCreateDate();
149    
150                                            Group group = groupPersistence.fetchByPrimaryKey(
151                                                    trashEntry.getGroupId());
152    
153                                            if (group == null) {
154                                                    return;
155                                            }
156    
157                                            Date date = getMaxAge(group);
158    
159                                            if (createDate.before(date) ||
160                                                    !TrashUtil.isTrashEnabled(group)) {
161    
162                                                    TrashHandler trashHandler =
163                                                            TrashHandlerRegistryUtil.getTrashHandler(
164                                                                    trashEntry.getClassName());
165    
166                                                    if (trashHandler != null) {
167                                                            trashHandler.deleteTrashEntry(
168                                                                    trashEntry.getClassPK());
169                                                    }
170                                            }
171                                    }
172    
173                            });
174                    actionableDynamicQuery.setTransactionConfig(
175                            DefaultActionableDynamicQuery.REQUIRES_NEW_TRANSACTION_CONFIG);
176    
177                    actionableDynamicQuery.performActions();
178            }
179    
180            @Override
181            public void deleteEntries(long groupId) {
182                    List<TrashEntry> entries = getEntries(groupId);
183    
184                    for (TrashEntry entry : entries) {
185                            deleteEntry(entry);
186                    }
187            }
188    
189            /**
190             * Deletes the trash entry with the primary key.
191             *
192             * @param  entryId the primary key of the trash entry
193             * @return the trash entry with the primary key
194             */
195            @Override
196            public TrashEntry deleteEntry(long entryId) {
197                    TrashEntry entry = trashEntryPersistence.fetchByPrimaryKey(entryId);
198    
199                    return deleteEntry(entry);
200            }
201    
202            /**
203             * Deletes the trash entry with the entity class name and primary key.
204             *
205             * @param  className the class name of entity
206             * @param  classPK the primary key of the entry
207             * @return the trash entry with the entity class name and primary key
208             */
209            @Override
210            public TrashEntry deleteEntry(String className, long classPK) {
211                    long classNameId = classNameLocalService.getClassNameId(className);
212    
213                    TrashEntry entry = trashEntryPersistence.fetchByC_C(
214                            classNameId, classPK);
215    
216                    return deleteEntry(entry);
217            }
218    
219            @Indexable(type = IndexableType.DELETE)
220            @Override
221            public TrashEntry deleteEntry(TrashEntry trashEntry) {
222                    if (trashEntry != null) {
223                            trashVersionPersistence.removeByEntryId(trashEntry.getEntryId());
224    
225                            trashEntry = trashEntryPersistence.remove(trashEntry);
226    
227                            systemEventLocalService.deleteSystemEvents(
228                                    trashEntry.getGroupId(), trashEntry.getSystemEventSetKey());
229                    }
230    
231                    return trashEntry;
232            }
233    
234            /**
235             * Returns the trash entry with the primary key.
236             *
237             * @param  entryId the primary key of the entry
238             * @return the trash entry with the primary key
239             */
240            @Override
241            public TrashEntry fetchEntry(long entryId) {
242                    return trashEntryPersistence.fetchByPrimaryKey(entryId);
243            }
244    
245            /**
246             * Returns the trash entry with the entity class name and primary key.
247             *
248             * @param  className the class name of the entity
249             * @param  classPK the primary key of the entity
250             * @return the trash entry with the entity class name and primary key
251             */
252            @Override
253            public TrashEntry fetchEntry(String className, long classPK) {
254                    long classNameId = classNameLocalService.getClassNameId(className);
255    
256                    return trashEntryPersistence.fetchByC_C(classNameId, classPK);
257            }
258    
259            /**
260             * Returns the trash entries with the matching group ID.
261             *
262             * @param  groupId the primary key of the group
263             * @return the trash entries with the group ID
264             */
265            @Override
266            public List<TrashEntry> getEntries(long groupId) {
267                    return trashEntryPersistence.findByGroupId(groupId);
268            }
269    
270            /**
271             * Returns a range of all the trash entries matching the group ID.
272             *
273             * @param  groupId the primary key of the group
274             * @param  start the lower bound of the range of trash entries to return
275             * @param  end the upper bound of the range of trash entries to return (not
276             *         inclusive)
277             * @return the range of matching trash entries
278             */
279            @Override
280            public List<TrashEntry> getEntries(long groupId, int start, int end) {
281                    return trashEntryPersistence.findByGroupId(groupId, start, end);
282            }
283    
284            /**
285             * Returns a range of all the trash entries matching the group ID.
286             *
287             * @param  groupId the primary key of the group
288             * @param  start the lower bound of the range of trash entries to return
289             * @param  end the upper bound of the range of trash entries to return (not
290             *         inclusive)
291             * @param  obc the comparator to order the trash entries (optionally
292             *         <code>null</code>)
293             * @return the range of matching trash entries ordered by comparator
294             *         <code>obc</code>
295             */
296            @Override
297            public List<TrashEntry> getEntries(
298                    long groupId, int start, int end, OrderByComparator<TrashEntry> obc) {
299    
300                    return trashEntryPersistence.findByGroupId(groupId, start, end, obc);
301            }
302    
303            @Override
304            public List<TrashEntry> getEntries(long groupId, String className) {
305                    long classNameId = classNameLocalService.getClassNameId(className);
306    
307                    return trashEntryPersistence.findByG_C(groupId, classNameId);
308            }
309    
310            /**
311             * Returns the number of trash entries with the group ID.
312             *
313             * @param  groupId the primary key of the group
314             * @return the number of matching trash entries
315             */
316            @Override
317            public int getEntriesCount(long groupId) {
318                    return trashEntryPersistence.countByGroupId(groupId);
319            }
320    
321            /**
322             * Returns the trash entry with the primary key.
323             *
324             * @param  entryId the primary key of the trash entry
325             * @return the trash entry with the primary key
326             */
327            @Override
328            public TrashEntry getEntry(long entryId) throws PortalException {
329                    return trashEntryPersistence.findByPrimaryKey(entryId);
330            }
331    
332            /**
333             * Returns the entry with the entity class name and primary key.
334             *
335             * @param  className the class name of the entity
336             * @param  classPK the primary key of the entity
337             * @return the trash entry with the entity class name and primary key
338             */
339            @Override
340            public TrashEntry getEntry(String className, long classPK)
341                    throws PortalException {
342    
343                    long classNameId = classNameLocalService.getClassNameId(className);
344    
345                    return trashEntryPersistence.findByC_C(classNameId, classPK);
346            }
347    
348            @Override
349            public Hits search(
350                    long companyId, long groupId, long userId, String keywords, int start,
351                    int end, Sort sort) {
352    
353                    try {
354                            Indexer<TrashEntry> indexer =
355                                    IndexerRegistryUtil.nullSafeGetIndexer(TrashEntry.class);
356    
357                            SearchContext searchContext = buildSearchContext(
358                                    companyId, groupId, userId, keywords, start, end, sort);
359    
360                            return indexer.search(searchContext);
361                    }
362                    catch (Exception e) {
363                            throw new SystemException(e);
364                    }
365            }
366    
367            @Override
368            public BaseModelSearchResult<TrashEntry> searchTrashEntries(
369                    long companyId, long groupId, long userId, String keywords, int start,
370                    int end, Sort sort) {
371    
372                    try {
373                            Indexer<TrashEntry> indexer =
374                                    IndexerRegistryUtil.nullSafeGetIndexer(TrashEntry.class);
375    
376                            SearchContext searchContext = buildSearchContext(
377                                    companyId, groupId, userId, keywords, start, end, sort);
378    
379                            Hits hits = indexer.search(searchContext);
380    
381                            List<TrashEntry> trashEntries = TrashUtil.getEntries(hits);
382    
383                            return new BaseModelSearchResult<>(trashEntries, hits.getLength());
384                    }
385                    catch (Exception e) {
386                            throw new SystemException(e);
387                    }
388            }
389    
390            protected SearchContext buildSearchContext(
391                    long companyId, long groupId, long userId, String keywords, int start,
392                    int end, Sort sort) {
393    
394                    SearchContext searchContext = new SearchContext();
395    
396                    searchContext.setCompanyId(companyId);
397                    searchContext.setEnd(end);
398                    searchContext.setKeywords(keywords);
399                    searchContext.setGroupIds(new long[] {groupId});
400    
401                    if (sort != null) {
402                            searchContext.setSorts(sort);
403                    }
404    
405                    searchContext.setStart(start);
406                    searchContext.setUserId(userId);
407    
408                    QueryConfig queryConfig = searchContext.getQueryConfig();
409    
410                    queryConfig.setHighlightEnabled(false);
411                    queryConfig.setScoreEnabled(false);
412    
413                    return searchContext;
414            }
415    
416            protected Date getMaxAge(Group group) throws PortalException {
417                    Calendar calendar = Calendar.getInstance();
418    
419                    calendar.setTime(new Date());
420    
421                    int maxAge = TrashUtil.getMaxAge(group);
422    
423                    calendar.add(Calendar.MINUTE, -maxAge);
424    
425                    return calendar.getTime();
426            }
427    
428    }