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