001/*
002 *  Copyright 2017 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.messagingconnector;
017
018import java.text.DateFormat;
019import java.text.SimpleDateFormat;
020import java.time.LocalDate;
021import java.util.ArrayList;
022import java.util.Date;
023import java.util.HashMap;
024import java.util.List;
025import java.util.Locale;
026import java.util.Map;
027
028import org.apache.avalon.framework.parameters.Parameters;
029import org.apache.avalon.framework.service.ServiceException;
030import org.apache.avalon.framework.service.ServiceManager;
031import org.apache.cocoon.acting.ServiceableAction;
032import org.apache.cocoon.environment.ObjectModelHelper;
033import org.apache.cocoon.environment.Redirector;
034import org.apache.cocoon.environment.Request;
035import org.apache.cocoon.environment.SourceResolver;
036import org.apache.commons.lang3.LocaleUtils;
037import org.apache.commons.lang3.StringUtils;
038
039import org.ametys.core.cocoon.JSonReader;
040import org.ametys.core.user.CurrentUserProvider;
041import org.ametys.core.user.UserIdentity;
042import org.ametys.core.user.UserManager;
043import org.ametys.core.util.DateUtils;
044import org.ametys.core.util.I18nUtils;
045import org.ametys.runtime.i18n.I18nizableText;
046
047/**
048 * 
049 * This class is the action used by the messaging connector plugin.
050 * It uses the correct mail server component.
051 *
052 */
053public class MessagingConnectorAction extends ServiceableAction
054{
055    /** Date format cache for different locale (date and time) */
056    protected static final Map<Locale, DateFormat> __DATETIME_FORMATS = new HashMap<>();
057    
058    /** Date format cache for different locale (time only) */
059    protected static final Map<Locale, DateFormat> __TIME_FORMATS = new HashMap<>();
060    
061    /** The output date format. */
062    protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("EEE d MMM H'h'mm");
063    
064    /** The max days parameter from the URL */
065    private static final String MAX_DAYS = "maxDays";
066
067    /** The max events parameter from the URL */
068    private static final String MAX_EVENTS = "maxEvents";
069    
070    /** mailServer selected */
071    protected String _mailServerId;
072
073    /** The current user provider */
074    protected CurrentUserProvider _currentUserProvider;
075
076    /** The user manager */
077    protected UserManager _usersManager;
078
079    /** The messaging connector that will be used*/
080    protected MessagingConnector _messagingConnector;
081
082    @Override
083    public void service(ServiceManager smanager) throws ServiceException
084    {
085        _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
086        _messagingConnector = (MessagingConnector) smanager.lookup(MessagingConnector.ROLE);
087        _usersManager = (UserManager) smanager.lookup(UserManager.ROLE);
088    }
089
090    @Override
091    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters)
092    {
093        Map<String, Object> result = new HashMap<>();
094        Request request = ObjectModelHelper.getRequest(objectModel);
095        
096        UserIdentity identity = _currentUserProvider.getUser();
097        if (identity != null)
098        {
099            result.put("unreadMessages", _messagingConnector.getUnreadEmailCount(identity));
100            
101            int maxDays = Integer.parseInt(request.getParameter(MAX_DAYS));
102            int maxEvents = Integer.parseInt(request.getParameter(MAX_EVENTS));
103            
104            LocalDate now = LocalDate.now();
105            Date fromDate = DateUtils.asDate(now);
106            Date untilDate = DateUtils.asDate(now.plusDays(maxDays));
107            
108            List<CalendarEvent> nextEvents = _messagingConnector.getEvents(identity, fromDate, untilDate, maxEvents);
109            
110            result.put("events", eventsToJson(nextEvents, getLocale(request, objectModel)));
111            result.put("nbNextEvents", _messagingConnector.getEventsCount(identity, fromDate, untilDate));
112        }
113
114        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
115        return EMPTY_MAP;
116    }
117    
118    /**
119     * Get the current locale
120     * @param request The request
121     * @param objectModel The object model
122     * @return the locale to use
123     */
124    protected Locale getLocale(Request request, Map objectModel)
125    {
126        String lang = request.getParameter("lang");
127        if (StringUtils.isNotEmpty(lang))
128        {
129            return LocaleUtils.toLocale(lang);
130        }
131        else
132        {
133            return org.apache.cocoon.i18n.I18nUtils.findLocale(objectModel, "locale", null, Locale.getDefault(), true);
134        }
135    }
136    
137    /**
138     * This methods is used to create a List with all the correct informations in order to be displayed by the plugin.
139     * 
140     * @param events the events to be displayed
141     * @param locale the locale of the user
142     * @return A list of Maps destined for Json
143     */
144    protected List<Map<String, Object>> eventsToJson(List<CalendarEvent> events, Locale locale) 
145    {
146        List<Map<String, Object>> eventsDisplayed = new ArrayList<>();
147        
148        for (CalendarEvent event : events)
149        {
150            Map<String, Object> eventDisplayed = new HashMap<>();
151            eventDisplayed.put("eventStartDateFormatted", _getFormattedDate(event.getStartDate(), locale));
152            eventDisplayed.put("eventEndDateFormatted", _getFormattedDate(event.getEndDate(), locale));
153            eventDisplayed.put("eventLocation", event.getLocation());
154            eventDisplayed.put("eventSubject", event.getSubject());
155
156            eventsDisplayed.add(eventDisplayed);
157        }
158
159        return eventsDisplayed;
160    }
161    
162    /**
163     * Format a Date to a String using a locale to set the correct date
164     * 
165     * @param date the date to format
166     * @param locale the locale of the user
167     * @return The date formated with the given locale
168     */
169    protected String _getFormattedDate(Date date, Locale locale)
170    {
171        // -- START DATE --
172        // Retrieves the desired date format for the current locale
173        boolean isSameDay = org.apache.commons.lang3.time.DateUtils.isSameDay(date, new Date());
174        Map<Locale, DateFormat> dateFormats = isSameDay ? __TIME_FORMATS : __DATETIME_FORMATS;
175        
176        DateFormat df = dateFormats.get(locale);
177        if (df == null)
178        {
179            String key = isSameDay ? "PLUGINS_MESSAGINGCONNECTOR_RDV_TIME_FORMAT" : "PLUGINS_MESSAGINGCONNECTOR_RDV_DATETIME_FORMAT";
180            String strFormat = I18nUtils.getInstance().translate(new I18nizableText("plugin.messaging-connector", key), locale.toString());
181            df = new SimpleDateFormat(strFormat, locale);
182            dateFormats.put(locale, df);
183        }
184        
185        return df.format(date);
186    }
187}