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.util.ArrayList;
021import java.util.Date;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Locale;
025import java.util.Map;
026
027import org.apache.avalon.framework.parameters.Parameters;
028import org.apache.avalon.framework.service.ServiceException;
029import org.apache.avalon.framework.service.ServiceManager;
030import org.apache.cocoon.acting.ServiceableAction;
031import org.apache.cocoon.environment.ObjectModelHelper;
032import org.apache.cocoon.environment.Redirector;
033import org.apache.cocoon.environment.Request;
034import org.apache.cocoon.environment.SourceResolver;
035import org.apache.commons.lang3.LocaleUtils;
036import org.apache.commons.lang3.StringUtils;
037
038import org.ametys.core.cocoon.JSonReader;
039import org.ametys.core.user.CurrentUserProvider;
040import org.ametys.core.user.UserIdentity;
041import org.ametys.core.user.UserManager;
042import org.ametys.core.util.I18nUtils;
043import org.ametys.plugins.messagingconnector.MessagingConnectorException.ExceptionType;
044import org.ametys.runtime.i18n.I18nizableText;
045
046/**
047 * 
048 * This class is the action used by the messaging connector plugin.
049 * It uses the correct mail server component.
050 *
051 */
052public class MessagingConnectorAction extends ServiceableAction
053{
054    /** Date format cache for different locale (date and time) */
055    protected static final Map<Locale, DateFormat> __DATETIME_FORMATS = new HashMap<>();
056    
057    /** Date format cache for different locale (time only) */
058    protected static final Map<Locale, DateFormat> __TIME_FORMATS = new HashMap<>();
059    
060    /** The output date format. */
061    protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("EEE d MMM H'h'mm");
062    
063    /** The max days parameter from the URL */
064    private static final String MAX_DAYS = "maxDays";
065
066    /** The max events parameter from the URL */
067    private static final String MAX_EVENTS = "maxEvents";
068    
069    /** mailServer selected */
070    protected String _mailServerId;
071
072    /** The current user provider */
073    protected CurrentUserProvider _currentUserProvider;
074
075    /** The user manager */
076    protected UserManager _usersManager;
077
078    /** The messaging connector that will be used*/
079    protected MessagingConnector _messagingConnector;
080
081    /** The I18N utils */
082    protected I18nUtils _i18nUtils;
083
084    @Override
085    public void service(ServiceManager smanager) throws ServiceException
086    {
087        _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
088        _messagingConnector = (MessagingConnector) smanager.lookup(MessagingConnector.ROLE);
089        _usersManager = (UserManager) smanager.lookup(UserManager.ROLE);
090        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
091    }
092
093    @Override
094    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters)
095    {
096        Map<String, Object> result = new HashMap<>();
097        Request request = ObjectModelHelper.getRequest(objectModel);
098        Boolean success = true;
099        try
100        {
101            UserIdentity identity = _currentUserProvider.getUser();
102            if (identity != null)
103            {
104                result.put("unreadMessages", _messagingConnector.getUnreadEmailCount(identity));
105                
106                int maxDays = Integer.parseInt(request.getParameter(MAX_DAYS));
107                int maxEvents = Integer.parseInt(request.getParameter(MAX_EVENTS));
108                
109                List<CalendarEvent> nextEvents = _messagingConnector.getEvents(identity, maxDays, maxEvents);
110                
111                result.put("events", eventsToJson(nextEvents, getLocale(request, objectModel)));
112                result.put("nbNextEvents", _messagingConnector.getEventsCount(identity, maxDays));
113            }
114        }
115        catch (MessagingConnectorException e)
116        {
117            success = false;
118            ExceptionType type = e.getType();
119            switch (type)
120            {
121                case TIMEOUT:
122                case UNAUTHORIZED:
123                case CONFIGURATION_EXCEPTION:
124                    result.put("error", type.name());
125                    I18nizableText errorMessage = new I18nizableText("plugin.messaging-connector", "PLUGINS_MESSAGINGCONNECTOR_ERROR_" + type.name().toUpperCase());
126                    result.put("message", errorMessage);
127                    break;
128                case UNKNOWN:
129                default:
130                    throw e;
131            }
132        }
133
134        result.put("success", success);
135        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
136        return EMPTY_MAP;
137    }
138    
139    /**
140     * Get the current locale
141     * @param request The request
142     * @param objectModel The object model
143     * @return the locale to use
144     */
145    protected Locale getLocale(Request request, Map objectModel)
146    {
147        String lang = request.getParameter("lang");
148        if (StringUtils.isNotEmpty(lang))
149        {
150            return LocaleUtils.toLocale(lang);
151        }
152        else
153        {
154            return org.apache.cocoon.i18n.I18nUtils.findLocale(objectModel, "locale", null, Locale.getDefault(), true);
155        }
156    }
157    
158    /**
159     * This methods is used to create a List with all the correct informations in order to be displayed by the plugin.
160     * 
161     * @param events the events to be displayed
162     * @param locale the locale of the user
163     * @return A list of Maps destined for Json
164     */
165    protected List<Map<String, Object>> eventsToJson(List<CalendarEvent> events, Locale locale) 
166    {
167        List<Map<String, Object>> eventsDisplayed = new ArrayList<>();
168        
169        for (CalendarEvent event : events)
170        {
171            Map<String, Object> eventDisplayed = new HashMap<>();
172            eventDisplayed.put("eventStartDateFormatted", _getFormattedDate(event.getStartDate(), locale));
173            eventDisplayed.put("eventEndDateFormatted", _getFormattedDate(event.getEndDate(), locale));
174            eventDisplayed.put("eventLocation", event.getLocation());
175            eventDisplayed.put("eventSubject", event.getSubject());
176
177            eventsDisplayed.add(eventDisplayed);
178        }
179
180        return eventsDisplayed;
181    }
182    
183    /**
184     * Format a Date to a String using a locale to set the correct date
185     * 
186     * @param date the date to format
187     * @param locale the locale of the user
188     * @return The date formated with the given locale
189     */
190    protected String _getFormattedDate(Date date, Locale locale)
191    {
192        // -- START DATE --
193        // Retrieves the desired date format for the current locale
194        boolean isSameDay = org.apache.commons.lang3.time.DateUtils.isSameDay(date, new Date());
195        Map<Locale, DateFormat> dateFormats = isSameDay ? __TIME_FORMATS : __DATETIME_FORMATS;
196        
197        DateFormat df = dateFormats.get(locale);
198        if (df == null)
199        {
200            String key = isSameDay ? "PLUGINS_MESSAGINGCONNECTOR_RDV_TIME_FORMAT" : "PLUGINS_MESSAGINGCONNECTOR_RDV_DATETIME_FORMAT";
201            String strFormat = _i18nUtils.translate(new I18nizableText("plugin.messaging-connector", key), locale.toString());
202            df = new SimpleDateFormat(strFormat, locale);
203            dateFormats.put(locale, df);
204        }
205        
206        return df.format(date);
207    }
208}