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