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