001    /**
002     * Copyright (c) 2000-2013 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.portal.service.impl;
016    
017    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskConstants;
018    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskExecutor;
019    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskStatus;
020    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskStatusRegistry;
021    import com.liferay.portal.kernel.bean.BeanReference;
022    import com.liferay.portal.kernel.exception.PortalException;
023    import com.liferay.portal.kernel.exception.SystemException;
024    import com.liferay.portal.kernel.json.JSONFactoryUtil;
025    import com.liferay.portal.kernel.messaging.DestinationNames;
026    import com.liferay.portal.kernel.messaging.Message;
027    import com.liferay.portal.kernel.messaging.MessageBusUtil;
028    import com.liferay.portal.kernel.repository.model.Folder;
029    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
030    import com.liferay.portal.kernel.util.ContentTypes;
031    import com.liferay.portal.kernel.util.OrderByComparator;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.model.BackgroundTask;
036    import com.liferay.portal.model.Lock;
037    import com.liferay.portal.model.User;
038    import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
039    import com.liferay.portal.service.ServiceContext;
040    import com.liferay.portal.service.base.BackgroundTaskLocalServiceBaseImpl;
041    import com.liferay.portal.util.PortletKeys;
042    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
043    
044    import java.io.File;
045    import java.io.InputStream;
046    import java.io.Serializable;
047    
048    import java.util.Date;
049    import java.util.List;
050    import java.util.Map;
051    import java.util.concurrent.Callable;
052    
053    /**
054     * @author Daniel Kocsis
055     * @author Michael C. Han
056     */
057    public class BackgroundTaskLocalServiceImpl
058            extends BackgroundTaskLocalServiceBaseImpl {
059    
060            @Override
061            public BackgroundTask addBackgroundTask(
062                            long userId, long groupId, String name,
063                            String[] servletContextNames, Class<?> taskExecutorClass,
064                            Map<String, Serializable> taskContextMap,
065                            ServiceContext serviceContext)
066                    throws PortalException, SystemException {
067    
068                    User user = userPersistence.findByPrimaryKey(userId);
069                    Date now = new Date();
070    
071                    final long backgroundTaskId = counterLocalService.increment();
072    
073                    BackgroundTask backgroundTask = backgroundTaskPersistence.create(
074                            backgroundTaskId);
075    
076                    backgroundTask.setCompanyId(user.getCompanyId());
077                    backgroundTask.setCreateDate(serviceContext.getCreateDate(now));
078                    backgroundTask.setGroupId(groupId);
079                    backgroundTask.setModifiedDate(serviceContext.getModifiedDate(now));
080                    backgroundTask.setUserId(userId);
081                    backgroundTask.setUserName(user.getFullName());
082                    backgroundTask.setName(name);
083                    backgroundTask.setServletContextNames(
084                            StringUtil.merge(servletContextNames));
085                    backgroundTask.setTaskExecutorClassName(taskExecutorClass.getName());
086    
087                    if (taskContextMap != null) {
088                            String taskContext = JSONFactoryUtil.serialize(taskContextMap);
089    
090                            backgroundTask.setTaskContext(taskContext);
091                    }
092    
093                    backgroundTask.setStatus(BackgroundTaskConstants.STATUS_NEW);
094    
095                    backgroundTaskPersistence.update(backgroundTask);
096    
097                    TransactionCommitCallbackRegistryUtil.registerCallback(
098                            new Callable<Void>() {
099    
100                                    @Override
101                                    public Void call() throws Exception {
102                                            Message message = new Message();
103    
104                                            message.put("backgroundTaskId", backgroundTaskId);
105    
106                                            MessageBusUtil.sendMessage(
107                                                    DestinationNames.BACKGROUND_TASK, message);
108    
109                                            return null;
110                                    }
111    
112                            });
113    
114                    return backgroundTask;
115            }
116    
117            @Override
118            public void addBackgroundTaskAttachment(
119                            long userId, long backgroundTaskId, String fileName, File file)
120                    throws PortalException, SystemException {
121    
122                    BackgroundTask backgroundTask = getBackgroundTask(backgroundTaskId);
123    
124                    Folder folder = backgroundTask.addAttachmentsFolder();
125    
126                    PortletFileRepositoryUtil.addPortletFileEntry(
127                            backgroundTask.getGroupId(), userId, BackgroundTask.class.getName(),
128                            backgroundTask.getPrimaryKey(), PortletKeys.BACKGROUND_TASK,
129                            folder.getFolderId(), file, fileName, ContentTypes.APPLICATION_ZIP,
130                            false);
131            }
132    
133            @Override
134            public void addBackgroundTaskAttachment(
135                            long userId, long backgroundTaskId, String fileName,
136                            InputStream inputStream)
137                    throws PortalException, SystemException {
138    
139                    BackgroundTask backgroundTask = getBackgroundTask(backgroundTaskId);
140    
141                    Folder folder = backgroundTask.addAttachmentsFolder();
142    
143                    PortletFileRepositoryUtil.addPortletFileEntry(
144                            backgroundTask.getGroupId(), userId, BackgroundTask.class.getName(),
145                            backgroundTask.getPrimaryKey(), PortletKeys.BACKGROUND_TASK,
146                            folder.getFolderId(), inputStream, fileName,
147                            ContentTypes.APPLICATION_ZIP, false);
148            }
149    
150            @Override
151            public BackgroundTask amendBackgroundTask(
152                            long backgroundTaskId, Map<String, Serializable> taskContextMap,
153                            int status, ServiceContext serviceContext)
154                    throws SystemException {
155    
156                    return amendBackgroundTask(
157                            backgroundTaskId, taskContextMap, status, null, serviceContext);
158            }
159    
160            @Override
161            public BackgroundTask amendBackgroundTask(
162                            long backgroundTaskId, Map<String, Serializable> taskContextMap,
163                            int status, String statusMessage, ServiceContext serviceContext)
164                    throws SystemException {
165    
166                    Date now = new Date();
167    
168                    BackgroundTask backgroundTask =
169                            backgroundTaskPersistence.fetchByPrimaryKey(backgroundTaskId);
170    
171                    if (backgroundTask == null) {
172                            return null;
173                    }
174    
175                    backgroundTask.setModifiedDate(serviceContext.getModifiedDate(now));
176    
177                    if (taskContextMap != null) {
178                            String taskContext = JSONFactoryUtil.serialize(taskContextMap);
179    
180                            backgroundTask.setTaskContext(taskContext);
181                    }
182    
183                    if ((status == BackgroundTaskConstants.STATUS_FAILED) ||
184                            (status == BackgroundTaskConstants.STATUS_SUCCESSFUL)) {
185    
186                            backgroundTask.setCompleted(true);
187                            backgroundTask.setCompletionDate(now);
188                    }
189    
190                    backgroundTask.setStatus(status);
191    
192                    if (Validator.isNotNull(statusMessage)) {
193                            backgroundTask.setStatusMessage(statusMessage);
194                    }
195    
196                    backgroundTaskPersistence.update(backgroundTask);
197    
198                    return backgroundTask;
199            }
200    
201            @Override
202            public void cleanUpBackgroundTasks() throws SystemException {
203                    List<BackgroundTask> backgroundTasks =
204                            backgroundTaskPersistence.findByStatus(
205                                    BackgroundTaskConstants.STATUS_IN_PROGRESS);
206    
207                    for (BackgroundTask backgroundTask : backgroundTasks) {
208                            backgroundTask.setStatus(BackgroundTaskConstants.STATUS_FAILED);
209    
210                            cleanUpBackgroundTask(
211                                    backgroundTask, BackgroundTaskConstants.STATUS_FAILED);
212                    }
213            }
214    
215            @Override
216            public BackgroundTask deleteBackgroundTask(BackgroundTask backgroundTask)
217                    throws PortalException, SystemException {
218    
219                    long folderId = backgroundTask.getAttachmentsFolderId();
220    
221                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
222                            PortletFileRepositoryUtil.deleteFolder(folderId);
223                    }
224    
225                    if (backgroundTask.getStatus() ==
226                                    BackgroundTaskConstants.STATUS_IN_PROGRESS) {
227    
228                            cleanUpBackgroundTask(
229                                    backgroundTask, BackgroundTaskConstants.STATUS_CANCELLED);
230                    }
231    
232                    return backgroundTaskPersistence.remove(backgroundTask);
233            }
234    
235            @Override
236            public BackgroundTask deleteBackgroundTask(long backgroundTaskId)
237                    throws PortalException, SystemException {
238    
239                    BackgroundTask backgroundTask =
240                            backgroundTaskPersistence.findByPrimaryKey(backgroundTaskId);
241    
242                    return deleteBackgroundTask(backgroundTask);
243            }
244    
245            @Override
246            public void deleteCompanyBackgroundTasks(long companyId)
247                    throws PortalException, SystemException {
248    
249                    List<BackgroundTask> backgroundTasks =
250                            backgroundTaskPersistence.findByCompanyId(companyId);
251    
252                    for (BackgroundTask backgroundTask : backgroundTasks) {
253                            deleteBackgroundTask(backgroundTask);
254                    }
255            }
256    
257            @Override
258            public void deleteGroupBackgroundTasks(long groupId)
259                    throws PortalException, SystemException {
260    
261                    List<BackgroundTask> backgroundTasks =
262                            backgroundTaskPersistence.findByGroupId(groupId);
263    
264                    for (BackgroundTask backgroundTask : backgroundTasks) {
265                            deleteBackgroundTask(backgroundTask);
266                    }
267            }
268    
269            @Override
270            public BackgroundTask fetchBackgroundTask(long backgroundTaskId)
271                    throws SystemException {
272    
273                    return backgroundTaskPersistence.fetchByPrimaryKey(backgroundTaskId);
274            }
275    
276            @Override
277            public BackgroundTask fetchFirstBackgroundTask(
278                            String taskExecutorClassName, int status)
279                    throws SystemException {
280    
281                    return fetchFirstBackgroundTask(taskExecutorClassName, status, null);
282            }
283    
284            @Override
285            public BackgroundTask fetchFirstBackgroundTask(
286                            String taskExecutorClassName, int status,
287                            OrderByComparator orderByComparator)
288                    throws SystemException {
289    
290                    return backgroundTaskPersistence.fetchByT_S_First(
291                            taskExecutorClassName, status, orderByComparator);
292            }
293    
294            @Override
295            public BackgroundTask getBackgroundTask(long backgroundTaskId)
296                    throws PortalException, SystemException {
297    
298                    return backgroundTaskPersistence.findByPrimaryKey(backgroundTaskId);
299            }
300    
301            @Override
302            public List<BackgroundTask> getBackgroundTasks(long groupId, int status)
303                    throws SystemException {
304    
305                    return backgroundTaskPersistence.findByG_S(groupId, status);
306            }
307    
308            @Override
309            public List<BackgroundTask> getBackgroundTasks(
310                            long groupId, String taskExecutorClassName)
311                    throws SystemException {
312    
313                    return backgroundTaskPersistence.findByG_T(
314                            groupId, taskExecutorClassName);
315            }
316    
317            @Override
318            public List<BackgroundTask> getBackgroundTasks(
319                            long groupId, String taskExecutorClassName, int status)
320                    throws SystemException {
321    
322                    return backgroundTaskPersistence.findByG_T_S(
323                            groupId, taskExecutorClassName, status);
324            }
325    
326            @Override
327            public List<BackgroundTask> getBackgroundTasks(
328                            long groupId, String taskExecutorClassName, int start, int end,
329                            OrderByComparator orderByComparator)
330                    throws SystemException {
331    
332                    return backgroundTaskPersistence.findByG_T(
333                            groupId, taskExecutorClassName, start, end, orderByComparator);
334            }
335    
336            @Override
337            public List<BackgroundTask> getBackgroundTasks(
338                            long groupId, String name, String taskExecutorClassName, int start,
339                            int end, OrderByComparator orderByComparator)
340                    throws SystemException {
341    
342                    return backgroundTaskPersistence.findByG_N_T(
343                            groupId, name, taskExecutorClassName, start, end,
344                            orderByComparator);
345            }
346    
347            @Override
348            public List<BackgroundTask> getBackgroundTasks(
349                            long groupId, String[] taskExecutorClassNames)
350                    throws SystemException {
351    
352                    return backgroundTaskPersistence.findByG_T(
353                            groupId, taskExecutorClassNames);
354            }
355    
356            @Override
357            public List<BackgroundTask> getBackgroundTasks(
358                            long groupId, String[] taskExecutorClassNames, int status)
359                    throws SystemException {
360    
361                    return backgroundTaskPersistence.findByG_T_S(
362                            groupId, taskExecutorClassNames, status);
363            }
364    
365            @Override
366            public List<BackgroundTask> getBackgroundTasks(
367                            long groupId, String[] taskExecutorClassNames, int start, int end,
368                            OrderByComparator orderByComparator)
369                    throws SystemException {
370    
371                    return backgroundTaskPersistence.findByG_T(
372                            groupId, taskExecutorClassNames, start, end, orderByComparator);
373            }
374    
375            @Override
376            public List<BackgroundTask> getBackgroundTasks(
377                            String taskExecutorClassName, int status)
378                    throws SystemException {
379    
380                    return backgroundTaskPersistence.findByT_S(
381                            taskExecutorClassName, status);
382            }
383    
384            @Override
385            public List<BackgroundTask> getBackgroundTasks(
386                            String taskExecutorClassName, int status, int start, int end,
387                            OrderByComparator orderByComparator)
388                    throws SystemException {
389    
390                    return backgroundTaskPersistence.findByT_S(
391                            taskExecutorClassName, status, start, end, orderByComparator);
392            }
393    
394            @Override
395            public List<BackgroundTask> getBackgroundTasks(
396                            String[] taskExecutorClassNames, int status)
397                    throws SystemException {
398    
399                    return backgroundTaskPersistence.findByT_S(
400                            taskExecutorClassNames, status);
401            }
402    
403            @Override
404            public List<BackgroundTask> getBackgroundTasks(
405                            String[] taskExecutorClassNames, int status, int start, int end,
406                            OrderByComparator orderByComparator)
407                    throws SystemException {
408    
409                    return backgroundTaskPersistence.findByT_S(
410                            taskExecutorClassNames, status, start, end, orderByComparator);
411            }
412    
413            @Override
414            public int getBackgroundTasksCount(
415                            long groupId, String taskExecutorClassName)
416                    throws SystemException {
417    
418                    return backgroundTaskPersistence.countByG_T(
419                            groupId, taskExecutorClassName);
420            }
421    
422            @Override
423            public int getBackgroundTasksCount(
424                            long groupId, String taskExecutorClassName, boolean completed)
425                    throws SystemException {
426    
427                    return backgroundTaskPersistence.countByG_T_C(
428                            groupId, taskExecutorClassName, completed);
429            }
430    
431            @Override
432            public int getBackgroundTasksCount(
433                            long groupId, String name, String taskExecutorClassName)
434                    throws SystemException {
435    
436                    return backgroundTaskPersistence.countByG_N_T(
437                            groupId, name, taskExecutorClassName);
438            }
439    
440            @Override
441            public int getBackgroundTasksCount(
442                            long groupId, String name, String taskExecutorClassName,
443                            boolean completed)
444                    throws SystemException {
445    
446                    return backgroundTaskPersistence.countByG_N_T_C(
447                            groupId, name, taskExecutorClassName, completed);
448            }
449    
450            @Override
451            public int getBackgroundTasksCount(
452                            long groupId, String[] taskExecutorClassNames)
453                    throws SystemException {
454    
455                    return backgroundTaskPersistence.countByG_T(
456                            groupId, taskExecutorClassNames);
457            }
458    
459            @Override
460            public int getBackgroundTasksCount(
461                            long groupId, String[] taskExecutorClassNames, boolean completed)
462                    throws SystemException {
463    
464                    return backgroundTaskPersistence.countByG_T_C(
465                            groupId, taskExecutorClassNames, completed);
466            }
467    
468            @Override
469            public String getBackgroundTaskStatusJSON(long backgroundTaskId) {
470                    BackgroundTaskStatus backgroundTaskStatus =
471                            _backgroundTaskStatusRegistry.getBackgroundTaskStatus(
472                                    backgroundTaskId);
473    
474                    if (backgroundTaskStatus != null) {
475                            return backgroundTaskStatus.getAttributesJSON();
476                    }
477    
478                    return StringPool.BLANK;
479            }
480    
481            @Override
482            public void resumeBackgroundTask(long backgroundTaskId)
483                    throws SystemException {
484    
485                    BackgroundTask backgroundTask =
486                            backgroundTaskPersistence.fetchByPrimaryKey(backgroundTaskId);
487    
488                    if ((backgroundTask == null) ||
489                            (backgroundTask.getStatus() !=
490                                    BackgroundTaskConstants.STATUS_QUEUED)) {
491    
492                            return;
493                    }
494    
495                    Message message = new Message();
496    
497                    message.put("backgroundTaskId", backgroundTaskId);
498    
499                    MessageBusUtil.sendMessage(DestinationNames.BACKGROUND_TASK, message);
500            }
501    
502            protected void cleanUpBackgroundTask(
503                    final BackgroundTask backgroundTask, final int status) {
504    
505                    try {
506                            Lock lock = lockLocalService.getLock(
507                                    BackgroundTaskExecutor.class.getName(),
508                                    backgroundTask.getTaskExecutorClassName());
509    
510                            String owner =
511                                    backgroundTask.getName() + StringPool.POUND +
512                                            backgroundTask.getBackgroundTaskId();
513    
514                            if (owner.equals(lock.getOwner())) {
515                                    lockLocalService.unlock(
516                                            BackgroundTaskExecutor.class.getName(),
517                                            backgroundTask.getTaskExecutorClassName());
518                            }
519                    }
520                    catch (Exception e) {
521                    }
522    
523                    TransactionCommitCallbackRegistryUtil.registerCallback(
524                            new Callable<Void>() {
525    
526                                    @Override
527                                    public Void call() throws Exception {
528                                            Message responseMessage = new Message();
529    
530                                            responseMessage.put(
531                                                    "backgroundTaskId",
532                                                    backgroundTask.getBackgroundTaskId());
533                                            responseMessage.put("name", backgroundTask.getName());
534                                            responseMessage.put("status", status);
535                                            responseMessage.put(
536                                                    "taskExecutorClassName",
537                                                    backgroundTask.getTaskExecutorClassName());
538    
539                                            MessageBusUtil.sendMessage(
540                                                    DestinationNames.BACKGROUND_TASK_STATUS,
541                                                    responseMessage);
542    
543                                            return null;
544                                    }
545    
546                            }
547                    );
548            }
549    
550            @BeanReference(type = BackgroundTaskStatusRegistry.class)
551            private BackgroundTaskStatusRegistry _backgroundTaskStatusRegistry;
552    
553    }