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.portlet.calendar.action;
016    
017    import com.liferay.portal.kernel.cal.DayAndPosition;
018    import com.liferay.portal.kernel.cal.Duration;
019    import com.liferay.portal.kernel.cal.Recurrence;
020    import com.liferay.portal.kernel.cal.TZSRecurrence;
021    import com.liferay.portal.kernel.portlet.LiferayWindowState;
022    import com.liferay.portal.kernel.sanitizer.SanitizerException;
023    import com.liferay.portal.kernel.servlet.SessionErrors;
024    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
025    import com.liferay.portal.kernel.util.Constants;
026    import com.liferay.portal.kernel.util.LocaleUtil;
027    import com.liferay.portal.kernel.util.ParamUtil;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.TimeZoneUtil;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.model.User;
032    import com.liferay.portal.security.auth.PrincipalException;
033    import com.liferay.portal.service.ServiceContext;
034    import com.liferay.portal.service.ServiceContextFactory;
035    import com.liferay.portal.struts.PortletAction;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portlet.asset.AssetCategoryException;
038    import com.liferay.portlet.asset.AssetTagException;
039    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
040    import com.liferay.portlet.calendar.EventDurationException;
041    import com.liferay.portlet.calendar.EventEndDateException;
042    import com.liferay.portlet.calendar.EventStartDateException;
043    import com.liferay.portlet.calendar.EventTitleException;
044    import com.liferay.portlet.calendar.NoSuchEventException;
045    import com.liferay.portlet.calendar.model.CalEvent;
046    import com.liferay.portlet.calendar.model.CalEventConstants;
047    import com.liferay.portlet.calendar.service.CalEventServiceUtil;
048    
049    import java.util.ArrayList;
050    import java.util.Calendar;
051    import java.util.List;
052    import java.util.Locale;
053    import java.util.TimeZone;
054    
055    import javax.portlet.ActionRequest;
056    import javax.portlet.ActionResponse;
057    import javax.portlet.PortletConfig;
058    import javax.portlet.RenderRequest;
059    import javax.portlet.RenderResponse;
060    import javax.portlet.WindowState;
061    
062    import org.apache.struts.action.ActionForm;
063    import org.apache.struts.action.ActionForward;
064    import org.apache.struts.action.ActionMapping;
065    
066    /**
067     * @author Brian Wing Shun Chan
068     */
069    public class EditEventAction extends PortletAction {
070    
071            @Override
072            public void processAction(
073                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
074                            ActionRequest actionRequest, ActionResponse actionResponse)
075                    throws Exception {
076    
077                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
078    
079                    try {
080                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
081                                    updateEvent(actionRequest);
082                            }
083                            else if (cmd.equals(Constants.DELETE)) {
084                                    deleteEvent(actionRequest);
085                            }
086    
087                            WindowState windowState = actionRequest.getWindowState();
088    
089                            if (!windowState.equals(LiferayWindowState.POP_UP)) {
090                                    sendRedirect(actionRequest, actionResponse);
091                            }
092                            else {
093                                    String redirect = PortalUtil.escapeRedirect(
094                                            ParamUtil.getString(actionRequest, "redirect"));
095    
096                                    if (Validator.isNotNull(redirect)) {
097                                            actionResponse.sendRedirect(redirect);
098                                    }
099                            }
100                    }
101                    catch (Exception e) {
102                            if (e instanceof NoSuchEventException ||
103                                    e instanceof PrincipalException) {
104    
105                                    SessionErrors.add(actionRequest, e.getClass());
106    
107                                    setForward(actionRequest, "portlet.calendar.error");
108                            }
109                            else if (e instanceof EventDurationException ||
110                                             e instanceof EventEndDateException ||
111                                             e instanceof EventStartDateException ||
112                                             e instanceof EventTitleException ||
113                                             e instanceof SanitizerException) {
114    
115                                    SessionErrors.add(actionRequest, e.getClass());
116                            }
117                            else if (e instanceof AssetCategoryException ||
118                                             e instanceof AssetTagException) {
119    
120                                    SessionErrors.add(actionRequest, e.getClass(), e);
121                            }
122                            else {
123                                    Throwable cause = e.getCause();
124    
125                                    if (cause instanceof SanitizerException) {
126                                            SessionErrors.add(actionRequest, SanitizerException.class);
127                                    }
128                                    else {
129                                            throw e;
130                                    }
131                            }
132                    }
133            }
134    
135            @Override
136            public ActionForward render(
137                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
138                            RenderRequest renderRequest, RenderResponse renderResponse)
139                    throws Exception {
140    
141                    try {
142                            ActionUtil.getEvent(renderRequest);
143                    }
144                    catch (Exception e) {
145                            if (e instanceof NoSuchEventException ||
146                                    e instanceof PrincipalException) {
147    
148                                    SessionErrors.add(renderRequest, e.getClass());
149    
150                                    return mapping.findForward("portlet.calendar.error");
151                            }
152                            else {
153                                    throw e;
154                            }
155                    }
156    
157                    return mapping.findForward(
158                            getForward(renderRequest, "portlet.calendar.edit_event"));
159            }
160    
161            protected void addWeeklyDayPos(
162                    ActionRequest actionRequest, List<DayAndPosition> list, int day) {
163    
164                    if (ParamUtil.getBoolean(actionRequest, "weeklyDayPos" + day)) {
165                            list.add(new DayAndPosition(day, 0));
166                    }
167            }
168    
169            protected void deleteEvent(ActionRequest actionRequest) throws Exception {
170                    long eventId = ParamUtil.getLong(actionRequest, "eventId");
171    
172                    CalEventServiceUtil.deleteEvent(eventId);
173            }
174    
175            protected void updateEvent(ActionRequest actionRequest) throws Exception {
176                    long eventId = ParamUtil.getLong(actionRequest, "eventId");
177    
178                    String title = ParamUtil.getString(actionRequest, "title");
179                    String description = ParamUtil.getString(actionRequest, "description");
180                    String location = ParamUtil.getString(actionRequest, "location");
181    
182                    int startDateMonth = ParamUtil.getInteger(
183                            actionRequest, "startDateMonth");
184                    int startDateDay = ParamUtil.getInteger(actionRequest, "startDateDay");
185                    int startDateYear = ParamUtil.getInteger(
186                            actionRequest, "startDateYear");
187                    int startDateHour = ParamUtil.getInteger(
188                            actionRequest, "startDateHour");
189                    int startDateMinute = ParamUtil.getInteger(
190                            actionRequest, "startDateMinute");
191                    int startDateAmPm = ParamUtil.getInteger(
192                            actionRequest, "startDateAmPm");
193    
194                    if (startDateAmPm == Calendar.PM) {
195                            startDateHour += 12;
196                    }
197    
198                    int durationHour = ParamUtil.getInteger(actionRequest, "durationHour");
199                    int durationMinute = ParamUtil.getInteger(
200                            actionRequest, "durationMinute");
201                    boolean allDay = ParamUtil.getBoolean(actionRequest, "allDay");
202    
203                    boolean timeZoneSensitive = false;
204    
205                    if (allDay) {
206                            timeZoneSensitive = false;
207                    }
208                    else {
209                            timeZoneSensitive = ParamUtil.getBoolean(
210                                    actionRequest, "timeZoneSensitive");
211                    }
212    
213                    String type = ParamUtil.getString(actionRequest, "type");
214    
215                    int endDateMonth = ParamUtil.getInteger(actionRequest, "endDateMonth");
216                    int endDateDay = ParamUtil.getInteger(actionRequest, "endDateDay");
217                    int endDateYear = ParamUtil.getInteger(actionRequest, "endDateYear");
218    
219                    boolean repeating = false;
220    
221                    int recurrenceType = ParamUtil.getInteger(
222                            actionRequest, "recurrenceType");
223    
224                    if (recurrenceType != Recurrence.NO_RECURRENCE) {
225                            repeating = true;
226                    }
227    
228                    Locale locale = null;
229                    TimeZone timeZone = null;
230    
231                    if (timeZoneSensitive) {
232                            User user = PortalUtil.getUser(actionRequest);
233    
234                            locale = user.getLocale();
235                            timeZone = user.getTimeZone();
236                    }
237                    else {
238                            locale = LocaleUtil.getDefault();
239                            timeZone = TimeZoneUtil.getTimeZone(StringPool.UTC);
240                    }
241    
242                    Calendar startDate = CalendarFactoryUtil.getCalendar(timeZone, locale);
243    
244                    startDate.set(Calendar.MONTH, startDateMonth);
245                    startDate.set(Calendar.DATE, startDateDay);
246                    startDate.set(Calendar.YEAR, startDateYear);
247                    startDate.set(Calendar.HOUR_OF_DAY, startDateHour);
248                    startDate.set(Calendar.MINUTE, startDateMinute);
249                    startDate.set(Calendar.SECOND, 0);
250                    startDate.set(Calendar.MILLISECOND, 0);
251    
252                    if (allDay) {
253                            startDate.set(Calendar.HOUR_OF_DAY, 0);
254                            startDate.set(Calendar.MINUTE, 0);
255                            startDate.set(Calendar.SECOND, 0);
256                            startDate.set(Calendar.MILLISECOND, 0);
257    
258                            durationHour = 24;
259                            durationMinute = 0;
260                    }
261    
262                    TZSRecurrence recurrence = null;
263    
264                    if (repeating) {
265                            Calendar recStartCal = null;
266    
267                            if (timeZoneSensitive) {
268                                    recStartCal = CalendarFactoryUtil.getCalendar(
269                                            TimeZoneUtil.getTimeZone(StringPool.UTC));
270    
271                                    recStartCal.setTime(startDate.getTime());
272                            }
273                            else {
274                                    recStartCal = (Calendar)startDate.clone();
275                            }
276    
277                            recurrence = new TZSRecurrence(
278                                    recStartCal, new Duration(1, 0, 0, 0), recurrenceType);
279    
280                            recurrence.setTimeZone(timeZone);
281    
282                            recurrence.setWeekStart(Calendar.SUNDAY);
283    
284                            if (recurrenceType == Recurrence.DAILY) {
285                                    int dailyType = ParamUtil.getInteger(
286                                            actionRequest, "dailyType");
287    
288                                    if (dailyType == 0) {
289                                            int dailyInterval = ParamUtil.getInteger(
290                                                    actionRequest, "dailyInterval", 1);
291    
292                                            recurrence.setInterval(dailyInterval);
293                                    }
294                                    else {
295                                            DayAndPosition[] dayPos = {
296                                                    new DayAndPosition(Calendar.MONDAY, 0),
297                                                    new DayAndPosition(Calendar.TUESDAY, 0),
298                                                    new DayAndPosition(Calendar.WEDNESDAY, 0),
299                                                    new DayAndPosition(Calendar.THURSDAY, 0),
300                                                    new DayAndPosition(Calendar.FRIDAY, 0)};
301    
302                                            recurrence.setByDay(dayPos);
303                                    }
304                            }
305                            else if (recurrenceType == Recurrence.WEEKLY) {
306                                    int weeklyInterval = ParamUtil.getInteger(
307                                            actionRequest, "weeklyInterval", 1);
308    
309                                    recurrence.setInterval(weeklyInterval);
310    
311                                    List<DayAndPosition> dayPos = new ArrayList<DayAndPosition>();
312    
313                                    addWeeklyDayPos(actionRequest, dayPos, Calendar.SUNDAY);
314                                    addWeeklyDayPos(actionRequest, dayPos, Calendar.MONDAY);
315                                    addWeeklyDayPos(actionRequest, dayPos, Calendar.TUESDAY);
316                                    addWeeklyDayPos(actionRequest, dayPos, Calendar.WEDNESDAY);
317                                    addWeeklyDayPos(actionRequest, dayPos, Calendar.THURSDAY);
318                                    addWeeklyDayPos(actionRequest, dayPos, Calendar.FRIDAY);
319                                    addWeeklyDayPos(actionRequest, dayPos, Calendar.SATURDAY);
320    
321                                    if (dayPos.size() == 0) {
322                                            dayPos.add(new DayAndPosition(Calendar.MONDAY, 0));
323                                    }
324    
325                                    recurrence.setByDay(
326                                            dayPos.toArray(new DayAndPosition[dayPos.size()]));
327                            }
328                            else if (recurrenceType == Recurrence.MONTHLY) {
329                                    int monthlyType = ParamUtil.getInteger(
330                                            actionRequest, "monthlyType");
331    
332                                    if (monthlyType == 0) {
333                                            int monthlyDay = ParamUtil.getInteger(
334                                                    actionRequest, "monthlyDay0");
335    
336                                            recurrence.setByMonthDay(new int[] {monthlyDay});
337    
338                                            int monthlyInterval = ParamUtil.getInteger(
339                                                    actionRequest, "monthlyInterval0", 1);
340    
341                                            recurrence.setInterval(monthlyInterval);
342                                    }
343                                    else {
344                                            int monthlyPos = ParamUtil.getInteger(
345                                                    actionRequest, "monthlyPos");
346                                            int monthlyDay = ParamUtil.getInteger(
347                                                    actionRequest, "monthlyDay1");
348    
349                                            DayAndPosition[] dayPos = {
350                                                    new DayAndPosition(monthlyDay, monthlyPos)};
351    
352                                            recurrence.setByDay(dayPos);
353    
354                                            int monthlyInterval = ParamUtil.getInteger(
355                                                    actionRequest, "monthlyInterval1", 1);
356    
357                                            recurrence.setInterval(monthlyInterval);
358                                    }
359                            }
360                            else if (recurrenceType == Recurrence.YEARLY) {
361                                    int yearlyType = ParamUtil.getInteger(
362                                            actionRequest, "yearlyType");
363    
364                                    if (yearlyType == 0) {
365                                            int yearlyMonth = ParamUtil.getInteger(
366                                                    actionRequest, "yearlyMonth0");
367                                            int yearlyDay = ParamUtil.getInteger(
368                                                    actionRequest, "yearlyDay0");
369    
370                                            recurrence.setByMonth(new int[] {yearlyMonth});
371                                            recurrence.setByMonthDay(new int[] {yearlyDay});
372    
373                                            int yearlyInterval = ParamUtil.getInteger(
374                                                    actionRequest, "yearlyInterval0", 1);
375    
376                                            recurrence.setInterval(yearlyInterval);
377                                    }
378                                    else {
379                                            int yearlyPos = ParamUtil.getInteger(
380                                                    actionRequest, "yearlyPos");
381                                            int yearlyDay = ParamUtil.getInteger(
382                                                    actionRequest, "yearlyDay1");
383                                            int yearlyMonth = ParamUtil.getInteger(
384                                                    actionRequest, "yearlyMonth1");
385    
386                                            DayAndPosition[] dayPos = {
387                                                    new DayAndPosition(yearlyDay, yearlyPos)};
388    
389                                            recurrence.setByDay(dayPos);
390    
391                                            recurrence.setByMonth(new int[] {yearlyMonth});
392    
393                                            int yearlyInterval = ParamUtil.getInteger(
394                                                    actionRequest, "yearlyInterval1", 1);
395    
396                                            recurrence.setInterval(yearlyInterval);
397                                    }
398                            }
399    
400                            int endDateType = ParamUtil.getInteger(
401                                    actionRequest, "endDateType");
402    
403                            if (endDateType == CalEventConstants.END_DATE_TYPE_END_AFTER) {
404                                    int endDateOccurrence = ParamUtil.getInteger(
405                                            actionRequest, "endDateOccurrence");
406    
407                                    recurrence.setOccurrence(endDateOccurrence);
408                            }
409                            else if (endDateType == CalEventConstants.END_DATE_TYPE_END_BY) {
410                                    Calendar endDate = CalendarFactoryUtil.getCalendar(timeZone);
411    
412                                    endDate.set(Calendar.MONTH, endDateMonth);
413                                    endDate.set(Calendar.DATE, endDateDay);
414                                    endDate.set(Calendar.YEAR, endDateYear);
415                                    endDate.set(Calendar.HOUR_OF_DAY, startDateHour);
416                                    endDate.set(Calendar.MINUTE, startDateMinute);
417                                    endDate.set(Calendar.SECOND, 0);
418                                    endDate.set(Calendar.MILLISECOND, 0);
419    
420                                    Calendar recEndCal = null;
421    
422                                    if (timeZoneSensitive) {
423                                            recEndCal = CalendarFactoryUtil.getCalendar(
424                                                    TimeZoneUtil.getTimeZone(StringPool.UTC));
425    
426                                            recEndCal.setTime(endDate.getTime());
427                                    }
428                                    else {
429                                            recEndCal = (Calendar)endDate.clone();
430                                    }
431    
432                                    recurrence.setUntil(recEndCal);
433                            }
434                    }
435    
436                    int remindBy = ParamUtil.getInteger(actionRequest, "remindBy");
437                    int firstReminder = ParamUtil.getInteger(
438                            actionRequest, "firstReminder");
439                    int secondReminder = ParamUtil.getInteger(
440                            actionRequest, "secondReminder");
441    
442                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
443                            CalEvent.class.getName(), actionRequest);
444    
445                    if (eventId <= 0) {
446    
447                            // Add event
448    
449                            CalEvent event = CalEventServiceUtil.addEvent(
450                                    title, description, location, startDateMonth, startDateDay,
451                                    startDateYear, startDateHour, startDateMinute, durationHour,
452                                    durationMinute, allDay, timeZoneSensitive, type, repeating,
453                                    recurrence, remindBy, firstReminder, secondReminder,
454                                    serviceContext);
455    
456                            AssetPublisherUtil.addAndStoreSelection(
457                                    actionRequest, CalEvent.class.getName(), event.getEventId(),
458                                    -1);
459                    }
460                    else {
461    
462                            // Update event
463    
464                            CalEventServiceUtil.updateEvent(
465                                    eventId, title, description, location, startDateMonth,
466                                    startDateDay, startDateYear, startDateHour, startDateMinute,
467                                    durationHour, durationMinute, allDay, timeZoneSensitive, type,
468                                    repeating, recurrence, remindBy, firstReminder, secondReminder,
469                                    serviceContext);
470                    }
471            }
472    
473    }