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                            String taskExecutorClassName, int status)
350                    throws SystemException {
351    
352                    return backgroundTaskPersistence.findByT_S(
353                            taskExecutorClassName, status);
354            }
355    
356            @Override
357            public List<BackgroundTask> getBackgroundTasks(
358                            String taskExecutorClassName, int status, int start, int end,
359                            OrderByComparator orderByComparator)
360                    throws SystemException {
361    
362                    return backgroundTaskPersistence.findByT_S(
363                            taskExecutorClassName, status, start, end, orderByComparator);
364            }
365    
366            @Override
367            public int getBackgroundTasksCount(
368                            long groupId, String taskExecutorClassName)
369                    throws SystemException {
370    
371                    return backgroundTaskPersistence.countByG_T(
372                            groupId, taskExecutorClassName);
373            }
374    
375            @Override
376            public int getBackgroundTasksCount(
377                            long groupId, String taskExecutorClassName, boolean completed)
378                    throws SystemException {
379    
380                    return backgroundTaskPersistence.countByG_T_C(
381                            groupId, taskExecutorClassName, completed);
382            }
383    
384            @Override
385            public int getBackgroundTasksCount(
386                            long groupId, String name, String taskExecutorClassName)
387                    throws SystemException {
388    
389                    return backgroundTaskPersistence.countByG_N_T(
390                            groupId, name, taskExecutorClassName);
391            }
392    
393            @Override
394            public int getBackgroundTasksCount(
395                            long groupId, String name, String taskExecutorClassName,
396                            boolean completed)
397                    throws SystemException {
398    
399                    return backgroundTaskPersistence.countByG_N_T_C(
400                            groupId, name, taskExecutorClassName, completed);
401            }
402    
403            @Override
404            public String getBackgroundTaskStatusJSON(long backgroundTaskId) {
405                    BackgroundTaskStatus backgroundTaskStatus =
406                            _backgroundTaskStatusRegistry.getBackgroundTaskStatus(
407                                    backgroundTaskId);
408    
409                    if (backgroundTaskStatus != null) {
410                            return backgroundTaskStatus.getAttributesJSON();
411                    }
412    
413                    return StringPool.BLANK;
414            }
415    
416            @Override
417            public void resumeBackgroundTask(long backgroundTaskId)
418                    throws SystemException {
419    
420                    BackgroundTask backgroundTask =
421                            backgroundTaskPersistence.fetchByPrimaryKey(backgroundTaskId);
422    
423                    if ((backgroundTask == null) ||
424                            (backgroundTask.getStatus() !=
425                                    BackgroundTaskConstants.STATUS_QUEUED)) {
426    
427                            return;
428                    }
429    
430                    Message message = new Message();
431    
432                    message.put("backgroundTaskId", backgroundTaskId);
433    
434                    MessageBusUtil.sendMessage(DestinationNames.BACKGROUND_TASK, message);
435            }
436    
437            protected void cleanUpBackgroundTask(
438                    final BackgroundTask backgroundTask, final int status) {
439    
440                    try {
441                            Lock lock = lockLocalService.getLock(
442                                    BackgroundTaskExecutor.class.getName(),
443                                    backgroundTask.getTaskExecutorClassName());
444    
445                            String owner =
446                                    backgroundTask.getName() + StringPool.POUND +
447                                            backgroundTask.getBackgroundTaskId();
448    
449                            if (owner.equals(lock.getOwner())) {
450                                    lockLocalService.unlock(
451                                            BackgroundTaskExecutor.class.getName(),
452                                            backgroundTask.getTaskExecutorClassName());
453                            }
454                    }
455                    catch (Exception e) {
456                    }
457    
458                    TransactionCommitCallbackRegistryUtil.registerCallback(
459                            new Callable<Void>() {
460    
461                                    @Override
462                                    public Void call() throws Exception {
463                                            Message responseMessage = new Message();
464    
465                                            responseMessage.put(
466                                                    "backgroundTaskId",
467                                                    backgroundTask.getBackgroundTaskId());
468                                            responseMessage.put("name", backgroundTask.getName());
469                                            responseMessage.put("status", status);
470                                            responseMessage.put(
471                                                    "taskExecutorClassName",
472                                                    backgroundTask.getTaskExecutorClassName());
473    
474                                            MessageBusUtil.sendMessage(
475                                                    DestinationNames.BACKGROUND_TASK_STATUS,
476                                                    responseMessage);
477    
478                                            return null;
479                                    }
480    
481                            }
482                    );
483            }
484    
485            @BeanReference(type = BackgroundTaskStatusRegistry.class)
486            private BackgroundTaskStatusRegistry _backgroundTaskStatusRegistry;
487    
488    }