001/*
002 *  Copyright 2015 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.linkdirectory;
017
018import java.io.UnsupportedEncodingException;
019import java.net.URLDecoder;
020import java.util.ArrayList;
021import java.util.Enumeration;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.apache.avalon.framework.parameters.Parameters;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.acting.ServiceableAction;
030import org.apache.cocoon.environment.ObjectModelHelper;
031import org.apache.cocoon.environment.Redirector;
032import org.apache.cocoon.environment.Request;
033import org.apache.cocoon.environment.SourceResolver;
034import org.apache.commons.lang3.StringUtils;
035
036import org.ametys.core.cocoon.ActionResultGenerator;
037import org.ametys.core.user.CurrentUserProvider;
038import org.ametys.core.user.UserIdentity;
039import org.ametys.core.userpref.UserPreferencesManager;
040import org.ametys.web.userpref.FOUserPreferencesConstants;
041
042/**
043 * Create or set user preferences attached to a link directory service or the link directory input data mode for front-end users
044 */
045public class LinkDirectorySetUserPreferencesAction extends ServiceableAction
046{
047    /** The user preferences manager. */
048    private UserPreferencesManager _userPrefManager;
049
050    private DirectoryHelper _directoryHelper;
051    
052    /** The current user provider */
053    private CurrentUserProvider _currentUserProvider;
054    
055    @Override
056    public void service(ServiceManager serviceManager) throws ServiceException
057    {
058        super.service(serviceManager);
059        _userPrefManager = (UserPreferencesManager) serviceManager.lookup(UserPreferencesManager.ROLE + ".FO");
060        _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
061        _directoryHelper = (DirectoryHelper) serviceManager.lookup(DirectoryHelper.ROLE);
062    }
063    
064    @Override
065    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
066    {
067        Map<String, Object> result = new HashMap<>();
068        Request request = ObjectModelHelper.getRequest(objectModel);
069        
070        // We save user preferences for the FO or BO users
071        UserIdentity user = _currentUserProvider.getUser();
072        if (user != null && StringUtils.isNotEmpty(user.getLogin()) && StringUtils.isNotEmpty(user.getPopulationId()))
073        {
074            Map<String, String> values = new HashMap<>();
075            
076            String siteName = _directoryHelper.getSiteName(request);
077            String language = _directoryHelper.getLanguage(request);
078            String zoneItemId = request.getParameter("zone-item-id");
079            
080            String storageContext = _getStorageContext(siteName, language, zoneItemId);
081            Map<String, String> contextVars = _getContextVars(siteName, language);
082            
083            values.put("checked-links", _getCheckedLinks(request));
084            
085            _userPrefManager.setUserPreferences(user, storageContext, contextVars, values);
086            
087            request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result);
088        }
089        
090        return EMPTY_MAP;
091    }
092
093    /**
094     * Get the appropriate storage context 
095     * @param siteName the name of the site
096     * @param language the language
097     * @param zoneItemId the id of the zone item if we deal with a service, null for an input data
098     * @return the storage context in which the user preferences will be kept
099     */
100    private String _getStorageContext(String siteName, String language, String zoneItemId)
101    {
102        return StringUtils.isEmpty(zoneItemId) ? siteName + "/" + language : siteName + "/" + language + "/" + zoneItemId;
103    }
104    
105    /**
106     * Get the checked link ids from the request
107     * @param request the request
108     * @return the comma-separated string of checked links ids
109     */
110    private String _getCheckedLinks(Request request)
111    {
112        List<String> checkedLinksIds = new ArrayList<> ();
113        Enumeration<String> parameterNames = request.getParameterNames();
114        while (parameterNames.hasMoreElements())
115        {
116            String parameterName = parameterNames.nextElement();
117            if (parameterName.startsWith("checkbox-"))
118            {
119                String isChecked = request.getParameter(parameterName);
120                if (isChecked.equals("true"))
121                {
122                    String decodedParameterName = parameterName;
123                    try
124                    {
125                        decodedParameterName = URLDecoder.decode(parameterName, "utf-8");
126                    }
127                    catch (UnsupportedEncodingException e)
128                    {
129                        // Nothing
130                    }
131                    
132                    checkedLinksIds.add(decodedParameterName.substring("checkbox-".length()));
133                }
134            }
135        }
136        
137        return StringUtils.join(checkedLinksIds, ',');
138    }
139    
140    private Map<String, String> _getContextVars(String siteName, String language)
141    {
142        Map<String, String> contextVars = new HashMap<>();
143        
144        contextVars.put(FOUserPreferencesConstants.CONTEXT_VAR_SITENAME, siteName);
145        contextVars.put(FOUserPreferencesConstants.CONTEXT_VAR_LANGUAGE, language);
146        
147        return contextVars;
148    }
149}