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    @Override
082    public void service(ServiceManager smanager) throws ServiceException
083    {
084        _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
085        _messagingConnector = (MessagingConnector) smanager.lookup(MessagingConnector.ROLE);
086        _usersManager = (UserManager) smanager.lookup(UserManager.ROLE);
087    }
088
089    @Override
090    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters)
091    {
092        Map<String, Object> result = new HashMap<>();
093        Request request = ObjectModelHelper.getRequest(objectModel);
094        Boolean success = true;
095        try
096        {
097            UserIdentity identity = _currentUserProvider.getUser();
098            if (identity != null)
099            {
100                result.put("unreadMessages", _messagingConnector.getUnreadEmailCount(identity));
101                
102                int maxDays = Integer.parseInt(request.getParameter(MAX_DAYS));
103                int maxEvents = Integer.parseInt(request.getParameter(MAX_EVENTS));
104                
105                List<CalendarEvent> nextEvents = _messagingConnector.getEvents(identity, maxDays, maxEvents);
106                
107                result.put("events", eventsToJson(nextEvents, getLocale(request, objectModel)));
108                result.put("nbNextEvents", _messagingConnector.getEventsCount(identity, maxDays));
109            }
110        }
111        catch (MessagingConnectorException e)
112        {
113            success = false;
114            ExceptionType type = e.getType();
115            switch (type)
116            {
117                case TIMEOUT:
118                case UNAUTHORIZED:
119                case CONFIGURATION_EXCEPTION:
120                    result.put("error", type.name());
121                    I18nizableText errorMessage = new I18nizableText("plugin.messaging-connector", "PLUGINS_MESSAGINGCONNECTOR_ERROR_" + type.name().toUpperCase());
122                    result.put("message", errorMessage);
123                    break;
124                case UNKNOWN:
125                default:
126                    throw e;
127            }
128        }
129
130        result.put("success", success);
131        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
132        return EMPTY_MAP;
133    }
134    
135    /**
136     * Get the current locale
137     * @param request The request
138     * @param objectModel The object model
139     * @return the locale to use
140     */
141    protected Locale getLocale(Request request, Map objectModel)
142    {
143        String lang = request.getParameter("lang");
144        if (StringUtils.isNotEmpty(lang))
145        {
146            return LocaleUtils.toLocale(lang);
147        }
148        else
149        {
150            return org.apache.cocoon.i18n.I18nUtils.findLocale(objectModel, "locale", null, Locale.getDefault(), true);
151        }
152    }
153    
154    /**
155     * This methods is used to create a List with all the correct informations in order to be displayed by the plugin.
156     * 
157     * @param events the events to be displayed
158     * @param locale the locale of the user
159     * @return A list of Maps destined for Json
160     */
161    protected List<Map<String, Object>> eventsToJson(List<CalendarEvent> events, Locale locale) 
162    {
163        List<Map<String, Object>> eventsDisplayed = new ArrayList<>();
164        
165        for (CalendarEvent event : events)
166        {
167            Map<String, Object> eventDisplayed = new HashMap<>();
168            eventDisplayed.put("eventStartDateFormatted", _getFormattedDate(event.getStartDate(), locale));
169            eventDisplayed.put("eventEndDateFormatted", _getFormattedDate(event.getEndDate(), locale));
170            eventDisplayed.put("eventLocation", event.getLocation());
171            eventDisplayed.put("eventSubject", event.getSubject());
172
173            eventsDisplayed.add(eventDisplayed);
174        }
175
176        return eventsDisplayed;
177    }
178    
179    /**
180     * Format a Date to a String using a locale to set the correct date
181     * 
182     * @param date the date to format
183     * @param locale the locale of the user
184     * @return The date formated with the given locale
185     */
186    protected String _getFormattedDate(Date date, Locale locale)
187    {
188        // -- START DATE --
189        // Retrieves the desired date format for the current locale
190        boolean isSameDay = org.apache.commons.lang3.time.DateUtils.isSameDay(date, new Date());
191        Map<Locale, DateFormat> dateFormats = isSameDay ? __TIME_FORMATS : __DATETIME_FORMATS;
192        
193        DateFormat df = dateFormats.get(locale);
194        if (df == null)
195        {
196            String key = isSameDay ? "PLUGINS_MESSAGINGCONNECTOR_RDV_TIME_FORMAT" : "PLUGINS_MESSAGINGCONNECTOR_RDV_DATETIME_FORMAT";
197            String strFormat = I18nUtils.getInstance().translate(new I18nizableText("plugin.messaging-connector", key), locale.toString());
198            df = new SimpleDateFormat(strFormat, locale);
199            dateFormats.put(locale, df);
200        }
201        
202        return df.format(date);
203    }
204}