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.scheduler;
016    
017    import com.liferay.portal.kernel.audit.AuditMessage;
018    import com.liferay.portal.kernel.audit.AuditRouterUtil;
019    import com.liferay.portal.kernel.cal.DayAndPosition;
020    import com.liferay.portal.kernel.cal.Duration;
021    import com.liferay.portal.kernel.cal.Recurrence;
022    import com.liferay.portal.kernel.cal.RecurrenceSerializer;
023    import com.liferay.portal.kernel.json.JSONFactoryUtil;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.messaging.DestinationNames;
027    import com.liferay.portal.kernel.messaging.Message;
028    import com.liferay.portal.kernel.scheduler.JobState;
029    import com.liferay.portal.kernel.scheduler.SchedulerEngine;
030    import com.liferay.portal.kernel.scheduler.SchedulerEngineClusterManager;
031    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelper;
032    import com.liferay.portal.kernel.scheduler.SchedulerEntry;
033    import com.liferay.portal.kernel.scheduler.SchedulerException;
034    import com.liferay.portal.kernel.scheduler.SchedulerLifecycle;
035    import com.liferay.portal.kernel.scheduler.StorageType;
036    import com.liferay.portal.kernel.scheduler.Trigger;
037    import com.liferay.portal.kernel.scheduler.TriggerFactoryUtil;
038    import com.liferay.portal.kernel.scheduler.TriggerState;
039    import com.liferay.portal.kernel.scheduler.messaging.SchedulerResponse;
040    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
041    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
042    import com.liferay.portal.kernel.util.InetAddressUtil;
043    import com.liferay.portal.kernel.util.ObjectValuePair;
044    import com.liferay.portal.kernel.util.ParamUtil;
045    import com.liferay.portal.kernel.util.PortalLifecycle;
046    import com.liferay.portal.kernel.util.StringPool;
047    import com.liferay.portal.model.CompanyConstants;
048    import com.liferay.portal.util.PortalUtil;
049    import com.liferay.portal.util.PropsValues;
050    
051    import java.util.ArrayList;
052    import java.util.Calendar;
053    import java.util.Date;
054    import java.util.List;
055    
056    import javax.portlet.PortletRequest;
057    
058    /**
059     * @author Michael C. Han
060     */
061    @DoPrivileged
062    public class SchedulerEngineHelperImpl implements SchedulerEngineHelper {
063    
064            @Override
065            public void addJob(
066                            Trigger trigger, StorageType storageType, String description,
067                            String destinationName, Message message,
068                            String messageListenerClassName, String portletId,
069                            int exceptionsMaxSize)
070                    throws SchedulerException {
071    
072                    if (message == null) {
073                            message = new Message();
074                    }
075    
076                    message.put(
077                            SchedulerEngine.MESSAGE_LISTENER_CLASS_NAME,
078                            messageListenerClassName);
079                    message.put(SchedulerEngine.PORTLET_ID, portletId);
080    
081                    schedule(
082                            trigger, storageType, description, destinationName, message,
083                            exceptionsMaxSize);
084            }
085    
086            @Override
087            public void addJob(
088                            Trigger trigger, StorageType storageType, String description,
089                            String destinationName, Object payload,
090                            String messageListenerClassName, String portletId,
091                            int exceptionsMaxSize)
092                    throws SchedulerException {
093    
094                    Message message = new Message();
095    
096                    message.setPayload(payload);
097    
098                    addJob(
099                            trigger, storageType, description, destinationName, message,
100                            messageListenerClassName, portletId, exceptionsMaxSize);
101            }
102    
103            @Override
104            public void addScriptingJob(
105                            Trigger trigger, StorageType storageType, String description,
106                            String language, String script, int exceptionsMaxSize)
107                    throws SchedulerException {
108    
109                    Message message = new Message();
110    
111                    message.put(SchedulerEngine.LANGUAGE, language);
112                    message.put(SchedulerEngine.SCRIPT, script);
113    
114                    schedule(
115                            trigger, storageType, description,
116                            DestinationNames.SCHEDULER_SCRIPTING, message, exceptionsMaxSize);
117            }
118    
119            @Override
120            public void auditSchedulerJobs(Message message, TriggerState triggerState)
121                    throws SchedulerException {
122    
123                    if (!PropsValues.AUDIT_MESSAGE_SCHEDULER_JOB) {
124                            return;
125                    }
126    
127                    try {
128                            AuditMessage auditMessage = new AuditMessage(
129                                    SchedulerEngine.AUDIT_ACTION, CompanyConstants.SYSTEM, 0,
130                                    StringPool.BLANK, SchedulerEngine.class.getName(), "0",
131                                    triggerState.toString(), new Date(),
132                                    JSONFactoryUtil.createJSONObject(
133                                            JSONFactoryUtil.serialize(message)));
134    
135                            auditMessage.setServerName(InetAddressUtil.getLocalHostName());
136                            auditMessage.setServerPort(PortalUtil.getPortalPort(false));
137    
138                            AuditRouterUtil.route(auditMessage);
139                    }
140                    catch (Exception e) {
141                            throw new SchedulerException(e);
142                    }
143            }
144    
145            @Override
146            public void delete(SchedulerEntry schedulerEntry, StorageType storageType)
147                    throws SchedulerException {
148    
149                    Trigger trigger = schedulerEntry.getTrigger();
150    
151                    delete(trigger.getJobName(), trigger.getGroupName(), storageType);
152            }
153    
154            @Override
155            public void delete(String groupName, StorageType storageType)
156                    throws SchedulerException {
157    
158                    _schedulerEngine.delete(namespaceGroupName(groupName, storageType));
159            }
160    
161            @Override
162            public void delete(
163                            String jobName, String groupName, StorageType storageType)
164                    throws SchedulerException {
165    
166                    _schedulerEngine.delete(
167                            jobName, namespaceGroupName(groupName, storageType));
168            }
169    
170            @Override
171            public String getCronText(Calendar calendar, boolean timeZoneSensitive) {
172                    return getCronText(
173                            null, calendar, timeZoneSensitive, Recurrence.NO_RECURRENCE);
174            }
175    
176            @Override
177            public String getCronText(
178                    PortletRequest portletRequest, Calendar calendar,
179                    boolean timeZoneSensitive, int recurrenceType) {
180    
181                    Calendar recurrenceCalendar = null;
182    
183                    if (timeZoneSensitive) {
184                            recurrenceCalendar = CalendarFactoryUtil.getCalendar();
185    
186                            recurrenceCalendar.setTime(calendar.getTime());
187                    }
188                    else {
189                            recurrenceCalendar = (Calendar)calendar.clone();
190                    }
191    
192                    Recurrence recurrence = new Recurrence(
193                            recurrenceCalendar, new Duration(1, 0, 0, 0), recurrenceType);
194    
195                    recurrence.setWeekStart(Calendar.SUNDAY);
196    
197                    if (recurrenceType == Recurrence.DAILY) {
198                            int dailyType = ParamUtil.getInteger(portletRequest, "dailyType");
199    
200                            if (dailyType == 0) {
201                                    int dailyInterval = ParamUtil.getInteger(
202                                            portletRequest, "dailyInterval", 1);
203    
204                                    recurrence.setInterval(dailyInterval);
205                            }
206                            else {
207                                    DayAndPosition[] dayPos = {
208                                            new DayAndPosition(Calendar.MONDAY, 0),
209                                            new DayAndPosition(Calendar.TUESDAY, 0),
210                                            new DayAndPosition(Calendar.WEDNESDAY, 0),
211                                            new DayAndPosition(Calendar.THURSDAY, 0),
212                                            new DayAndPosition(Calendar.FRIDAY, 0)};
213    
214                                    recurrence.setByDay(dayPos);
215                            }
216                    }
217                    else if (recurrenceType == Recurrence.WEEKLY) {
218                            int weeklyInterval = ParamUtil.getInteger(
219                                    portletRequest, "weeklyInterval", 1);
220    
221                            recurrence.setInterval(weeklyInterval);
222    
223                            List<DayAndPosition> dayPos = new ArrayList<DayAndPosition>();
224    
225                            addWeeklyDayPos(portletRequest, dayPos, Calendar.SUNDAY);
226                            addWeeklyDayPos(portletRequest, dayPos, Calendar.MONDAY);
227                            addWeeklyDayPos(portletRequest, dayPos, Calendar.TUESDAY);
228                            addWeeklyDayPos(portletRequest, dayPos, Calendar.WEDNESDAY);
229                            addWeeklyDayPos(portletRequest, dayPos, Calendar.THURSDAY);
230                            addWeeklyDayPos(portletRequest, dayPos, Calendar.FRIDAY);
231                            addWeeklyDayPos(portletRequest, dayPos, Calendar.SATURDAY);
232    
233                            if (dayPos.size() == 0) {
234                                    dayPos.add(new DayAndPosition(Calendar.MONDAY, 0));
235                            }
236    
237                            recurrence.setByDay(dayPos.toArray(new DayAndPosition[0]));
238                    }
239                    else if (recurrenceType == Recurrence.MONTHLY) {
240                            int monthlyType = ParamUtil.getInteger(
241                                    portletRequest, "monthlyType");
242    
243                            if (monthlyType == 0) {
244                                    int monthlyDay = ParamUtil.getInteger(
245                                            portletRequest, "monthlyDay0", 1);
246    
247                                    recurrence.setByMonthDay(new int[] {monthlyDay});
248    
249                                    int monthlyInterval = ParamUtil.getInteger(
250                                            portletRequest, "monthlyInterval0", 1);
251    
252                                    recurrence.setInterval(monthlyInterval);
253                            }
254                            else {
255                                    int monthlyPos = ParamUtil.getInteger(
256                                            portletRequest, "monthlyPos");
257                                    int monthlyDay = ParamUtil.getInteger(
258                                            portletRequest, "monthlyDay1");
259    
260                                    DayAndPosition[] dayPos = {
261                                            new DayAndPosition(monthlyDay, monthlyPos)};
262    
263                                    recurrence.setByDay(dayPos);
264    
265                                    int monthlyInterval = ParamUtil.getInteger(
266                                            portletRequest, "monthlyInterval1", 1);
267    
268                                    recurrence.setInterval(monthlyInterval);
269                            }
270                    }
271                    else if (recurrenceType == Recurrence.YEARLY) {
272                            int yearlyType = ParamUtil.getInteger(portletRequest, "yearlyType");
273    
274                            if (yearlyType == 0) {
275                                    int yearlyMonth = ParamUtil.getInteger(
276                                            portletRequest, "yearlyMonth0");
277                                    int yearlyDay = ParamUtil.getInteger(
278                                            portletRequest, "yearlyDay0", 1);
279    
280                                    recurrence.setByMonth(new int[] {yearlyMonth});
281                                    recurrence.setByMonthDay(new int[] {yearlyDay});
282    
283                                    int yearlyInterval = ParamUtil.getInteger(
284                                            portletRequest, "yearlyInterval0", 1);
285    
286                                    recurrence.setInterval(yearlyInterval);
287                            }
288                            else {
289                                    int yearlyPos = ParamUtil.getInteger(
290                                            portletRequest, "yearlyPos");
291                                    int yearlyDay = ParamUtil.getInteger(
292                                            portletRequest, "yearlyDay1");
293                                    int yearlyMonth = ParamUtil.getInteger(
294                                            portletRequest, "yearlyMonth1");
295    
296                                    DayAndPosition[] dayPos = {
297                                            new DayAndPosition(yearlyDay, yearlyPos)};
298    
299                                    recurrence.setByDay(dayPos);
300    
301                                    recurrence.setByMonth(new int[] {yearlyMonth});
302    
303                                    int yearlyInterval = ParamUtil.getInteger(
304                                            portletRequest, "yearlyInterval1", 1);
305    
306                                    recurrence.setInterval(yearlyInterval);
307                            }
308                    }
309    
310                    return RecurrenceSerializer.toCronText(recurrence);
311            }
312    
313            @Override
314            public Date getEndTime(SchedulerResponse schedulerResponse) {
315                    Message message = schedulerResponse.getMessage();
316    
317                    JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
318    
319                    TriggerState triggerState = jobState.getTriggerState();
320    
321                    if (triggerState.equals(TriggerState.NORMAL) ||
322                            triggerState.equals(TriggerState.PAUSED)) {
323    
324                            return (Date)message.get(SchedulerEngine.END_TIME);
325                    }
326                    else {
327                            return jobState.getTriggerDate(SchedulerEngine.END_TIME);
328                    }
329            }
330    
331            @Override
332            public Date getEndTime(
333                            String jobName, String groupName, StorageType storageType)
334                    throws SchedulerException {
335    
336                    SchedulerResponse schedulerResponse = getScheduledJob(
337                            jobName, groupName, storageType);
338    
339                    if (schedulerResponse != null) {
340                            return getEndTime(schedulerResponse);
341                    }
342    
343                    return null;
344            }
345    
346            @Override
347            public Date getFinalFireTime(SchedulerResponse schedulerResponse) {
348                    Message message = schedulerResponse.getMessage();
349    
350                    JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
351    
352                    TriggerState triggerState = jobState.getTriggerState();
353    
354                    if (triggerState.equals(TriggerState.NORMAL) ||
355                            triggerState.equals(TriggerState.PAUSED)) {
356    
357                            return (Date)message.get(SchedulerEngine.FINAL_FIRE_TIME);
358                    }
359                    else {
360                            return jobState.getTriggerDate(SchedulerEngine.FINAL_FIRE_TIME);
361                    }
362            }
363    
364            @Override
365            public Date getFinalFireTime(
366                            String jobName, String groupName, StorageType storageType)
367                    throws SchedulerException {
368    
369                    SchedulerResponse schedulerResponse = getScheduledJob(
370                            jobName, groupName, storageType);
371    
372                    if (schedulerResponse != null) {
373                            return getFinalFireTime(schedulerResponse);
374                    }
375    
376                    return null;
377            }
378    
379            @Override
380            public ObjectValuePair<Exception, Date>[] getJobExceptions(
381                    SchedulerResponse schedulerResponse) {
382    
383                    Message message = schedulerResponse.getMessage();
384    
385                    JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
386    
387                    return jobState.getExceptions();
388            }
389    
390            @Override
391            public ObjectValuePair<Exception, Date>[] getJobExceptions(
392                            String jobName, String groupName, StorageType storageType)
393                    throws SchedulerException {
394    
395                    SchedulerResponse schedulerResponse = getScheduledJob(
396                            jobName, groupName, storageType);
397    
398                    if (schedulerResponse != null) {
399                            return getJobExceptions(schedulerResponse);
400                    }
401    
402                    return null;
403            }
404    
405            @Override
406            public TriggerState getJobState(SchedulerResponse schedulerResponse) {
407                    Message message = schedulerResponse.getMessage();
408    
409                    JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
410    
411                    return jobState.getTriggerState();
412            }
413    
414            @Override
415            public TriggerState getJobState(
416                            String jobName, String groupName, StorageType storageType)
417                    throws SchedulerException {
418    
419                    SchedulerResponse schedulerResponse = getScheduledJob(
420                            jobName, groupName, storageType);
421    
422                    if (schedulerResponse != null) {
423                            return getJobState(schedulerResponse);
424                    }
425    
426                    return null;
427            }
428    
429            @Override
430            public Date getNextFireTime(SchedulerResponse schedulerResponse) {
431                    Message message = schedulerResponse.getMessage();
432    
433                    JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
434    
435                    TriggerState triggerState = jobState.getTriggerState();
436    
437                    if (triggerState.equals(TriggerState.NORMAL) ||
438                            triggerState.equals(TriggerState.PAUSED)) {
439    
440                            return (Date)message.get(SchedulerEngine.NEXT_FIRE_TIME);
441                    }
442                    else {
443                            return jobState.getTriggerDate(SchedulerEngine.NEXT_FIRE_TIME);
444                    }
445            }
446    
447            @Override
448            public Date getNextFireTime(
449                            String jobName, String groupName, StorageType storageType)
450                    throws SchedulerException {
451    
452                    SchedulerResponse schedulerResponse = getScheduledJob(
453                            jobName, groupName, storageType);
454    
455                    if (schedulerResponse != null) {
456                            return getNextFireTime(schedulerResponse);
457                    }
458    
459                    return null;
460            }
461    
462            @Override
463            public Date getPreviousFireTime(SchedulerResponse schedulerResponse) {
464                    Message message = schedulerResponse.getMessage();
465    
466                    JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
467    
468                    TriggerState triggerState = jobState.getTriggerState();
469    
470                    if (triggerState.equals(TriggerState.NORMAL) ||
471                            triggerState.equals(TriggerState.PAUSED)) {
472    
473                            return (Date)message.get(SchedulerEngine.PREVIOUS_FIRE_TIME);
474                    }
475                    else {
476                            return jobState.getTriggerDate(SchedulerEngine.PREVIOUS_FIRE_TIME);
477                    }
478            }
479    
480            @Override
481            public Date getPreviousFireTime(
482                            String jobName, String groupName, StorageType storageType)
483                    throws SchedulerException {
484    
485                    SchedulerResponse schedulerResponse = getScheduledJob(
486                            jobName, groupName, storageType);
487    
488                    if (schedulerResponse != null) {
489                            return getPreviousFireTime(schedulerResponse);
490                    }
491    
492                    return null;
493            }
494    
495            @Override
496            public SchedulerResponse getScheduledJob(
497                            String jobName, String groupName, StorageType storageType)
498                    throws SchedulerException {
499    
500                    return _schedulerEngine.getScheduledJob(
501                            jobName, namespaceGroupName(groupName, storageType));
502            }
503    
504            @Override
505            public List<SchedulerResponse> getScheduledJobs()
506                    throws SchedulerException {
507    
508                    return _schedulerEngine.getScheduledJobs();
509            }
510    
511            @Override
512            public List<SchedulerResponse> getScheduledJobs(StorageType storageType)
513                    throws SchedulerException {
514    
515                    List<SchedulerResponse> schedulerResponses =
516                            new ArrayList<SchedulerResponse>();
517    
518                    for (SchedulerResponse schedulerResponse :
519                                    _schedulerEngine.getScheduledJobs()) {
520    
521                            if (storageType.equals(schedulerResponse.getStorageType())) {
522                                    schedulerResponses.add(schedulerResponse);
523                            }
524                    }
525    
526                    return schedulerResponses;
527            }
528    
529            @Override
530            public List<SchedulerResponse> getScheduledJobs(
531                            String groupName, StorageType storageType)
532                    throws SchedulerException {
533    
534                    return _schedulerEngine.getScheduledJobs(
535                            namespaceGroupName(groupName, storageType));
536            }
537    
538            @Override
539            public Date getStartTime(SchedulerResponse schedulerResponse) {
540                    Message message = schedulerResponse.getMessage();
541    
542                    JobState jobState = (JobState)message.get(SchedulerEngine.JOB_STATE);
543    
544                    TriggerState triggerState = jobState.getTriggerState();
545    
546                    if (triggerState.equals(TriggerState.NORMAL) ||
547                            triggerState.equals(TriggerState.PAUSED)) {
548    
549                            return (Date)message.get(SchedulerEngine.START_TIME);
550                    }
551                    else {
552                            return jobState.getTriggerDate(SchedulerEngine.START_TIME);
553                    }
554            }
555    
556            @Override
557            public Date getStartTime(
558                            String jobName, String groupName, StorageType storageType)
559                    throws SchedulerException {
560    
561                    SchedulerResponse schedulerResponse = getScheduledJob(
562                            jobName, groupName, storageType);
563    
564                    if (schedulerResponse != null) {
565                            return getStartTime(schedulerResponse);
566                    }
567    
568                    return null;
569            }
570    
571            @Override
572            public void initialize() throws SchedulerException {
573                    if (_schedulerEngineClusterManager != null) {
574                            _schedulerEngineClusterManager.initialize();
575                    }
576    
577                    SchedulerLifecycle schedulerLifecycle = new SchedulerLifecycle();
578    
579                    schedulerLifecycle.registerPortalLifecycle(PortalLifecycle.METHOD_INIT);
580            }
581    
582            @Override
583            public String namespaceGroupName(
584                    String groupName, StorageType storageType) {
585    
586                    return storageType.toString().concat(StringPool.POUND).concat(
587                            groupName);
588            }
589    
590            @Override
591            public void pause(String groupName, StorageType storageType)
592                    throws SchedulerException {
593    
594                    _schedulerEngine.pause(namespaceGroupName(groupName, storageType));
595            }
596    
597            @Override
598            public void pause(String jobName, String groupName, StorageType storageType)
599                    throws SchedulerException {
600    
601                    _schedulerEngine.pause(
602                            jobName, namespaceGroupName(groupName, storageType));
603            }
604    
605            @Override
606            public void resume(String groupName, StorageType storageType)
607                    throws SchedulerException {
608    
609                    _schedulerEngine.resume(namespaceGroupName(groupName, storageType));
610            }
611    
612            @Override
613            public void resume(
614                            String jobName, String groupName, StorageType storageType)
615                    throws SchedulerException {
616    
617                    _schedulerEngine.resume(
618                            jobName, namespaceGroupName(groupName, storageType));
619            }
620    
621            @Override
622            public void schedule(
623                            SchedulerEntry schedulerEntry, StorageType storageType,
624                            String portletId, int exceptionsMaxSize)
625                    throws SchedulerException {
626    
627                    Message message = new Message();
628    
629                    message.put(
630                            SchedulerEngine.MESSAGE_LISTENER_CLASS_NAME,
631                            schedulerEntry.getEventListenerClass());
632                    message.put(SchedulerEngine.PORTLET_ID, portletId);
633    
634                    schedule(
635                            schedulerEntry.getTrigger(), storageType,
636                            schedulerEntry.getDescription(),
637                            DestinationNames.SCHEDULER_DISPATCH, message, exceptionsMaxSize);
638            }
639    
640            @Override
641            public void schedule(
642                            Trigger trigger, StorageType storageType, String description,
643                            String destinationName, Message message, int exceptionsMaxSize)
644                    throws SchedulerException {
645    
646                    if (message == null) {
647                            message = new Message();
648                    }
649    
650                    message.put(SchedulerEngine.EXCEPTIONS_MAX_SIZE, exceptionsMaxSize);
651    
652                    trigger = TriggerFactoryUtil.buildTrigger(
653                            trigger.getTriggerType(), trigger.getJobName(),
654                            namespaceGroupName(trigger.getGroupName(), storageType),
655                            trigger.getStartDate(), trigger.getEndDate(),
656                            trigger.getTriggerContent());
657    
658                    _schedulerEngine.schedule(
659                            trigger, description, destinationName, message);
660            }
661    
662            @Override
663            public void schedule(
664                            Trigger trigger, StorageType storageType, String description,
665                            String destinationName, Object payload, int exceptionsMaxSize)
666                    throws SchedulerException {
667    
668                    Message message = new Message();
669    
670                    message.setPayload(payload);
671    
672                    schedule(
673                            trigger, storageType, description, destinationName, message,
674                            exceptionsMaxSize);
675            }
676    
677            public void setSchedulerEngine(SchedulerEngine schedulerEngine) {
678                    _schedulerEngine = schedulerEngine;
679    
680                    if (schedulerEngine instanceof SchedulerEngineClusterManager) {
681                            _schedulerEngineClusterManager =
682                                    (SchedulerEngineClusterManager)schedulerEngine;
683                    }
684            }
685    
686            @Override
687            public void shutdown() throws SchedulerException {
688                    _schedulerEngine.shutdown();
689            }
690    
691            @Override
692            public void start() throws SchedulerException {
693                    _schedulerEngine.start();
694            }
695    
696            @Override
697            public void suppressError(
698                            String jobName, String groupName, StorageType storageType)
699                    throws SchedulerException {
700    
701                    _schedulerEngine.suppressError(
702                            jobName, namespaceGroupName(groupName, storageType));
703            }
704    
705            @Override
706            public void unschedule(
707                            SchedulerEntry schedulerEntry, StorageType storageType)
708                    throws SchedulerException {
709    
710                    Trigger trigger = schedulerEntry.getTrigger();
711    
712                    unschedule(trigger.getJobName(), trigger.getGroupName(), storageType);
713            }
714    
715            @Override
716            public void unschedule(String groupName, StorageType storageType)
717                    throws SchedulerException {
718    
719                    _schedulerEngine.unschedule(namespaceGroupName(groupName, storageType));
720            }
721    
722            @Override
723            public void unschedule(
724                            String jobName, String groupName, StorageType storageType)
725                    throws SchedulerException {
726    
727                    _schedulerEngine.unschedule(
728                            jobName, namespaceGroupName(groupName, storageType));
729            }
730    
731            @Override
732            public void update(
733                            String jobName, String groupName, StorageType storageType,
734                            String description, String language, String script,
735                            int exceptionsMaxSize)
736                    throws SchedulerException {
737    
738                    SchedulerResponse schedulerResponse = getScheduledJob(
739                            jobName, groupName, storageType);
740    
741                    if (schedulerResponse == null) {
742                            return;
743                    }
744    
745                    Trigger trigger = schedulerResponse.getTrigger();
746    
747                    if (trigger == null) {
748                            return;
749                    }
750    
751                    Message message = schedulerResponse.getMessage();
752    
753                    if (message == null) {
754                            return;
755                    }
756    
757                    addScriptingJob(
758                            trigger, storageType, description, language, script,
759                            exceptionsMaxSize);
760            }
761    
762            @Override
763            public void update(Trigger trigger, StorageType storageType)
764                    throws SchedulerException {
765    
766                    trigger = TriggerFactoryUtil.buildTrigger(
767                            trigger.getTriggerType(), trigger.getJobName(),
768                            namespaceGroupName(trigger.getGroupName(), storageType),
769                            trigger.getStartDate(), trigger.getEndDate(),
770                            trigger.getTriggerContent());
771    
772                    _schedulerEngine.update(trigger);
773            }
774    
775            @Override
776            public void updateMemorySchedulerClusterMaster() throws SchedulerException {
777                    if (_schedulerEngineClusterManager == null) {
778                            _log.error(
779                                    "Unable to update memory scheduler cluster master because " +
780                                            "the portal is not using a clustered scheduler engine");
781    
782                            return;
783                    }
784    
785                    _schedulerEngineClusterManager.updateMemorySchedulerClusterMaster();
786            }
787    
788            protected void addWeeklyDayPos(
789                    PortletRequest portletRequest, List<DayAndPosition> list, int day) {
790    
791                    if (ParamUtil.getBoolean(portletRequest, "weeklyDayPos" + day)) {
792                            list.add(new DayAndPosition(day, 0));
793                    }
794            }
795    
796            private static Log _log = LogFactoryUtil.getLog(
797                    SchedulerEngineHelperImpl.class);
798    
799            private SchedulerEngine _schedulerEngine;
800            private SchedulerEngineClusterManager _schedulerEngineClusterManager;
801    
802    }