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.util.HashMap;
019import java.util.Map;
020
021import org.apache.avalon.framework.parameters.Parameters;
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.cocoon.acting.ServiceableAction;
025import org.apache.cocoon.environment.ObjectModelHelper;
026import org.apache.cocoon.environment.Redirector;
027import org.apache.cocoon.environment.Request;
028import org.apache.cocoon.environment.SourceResolver;
029import org.apache.commons.lang3.StringUtils;
030
031import org.ametys.core.cocoon.ActionResultGenerator;
032import org.ametys.core.user.CurrentUserProvider;
033import org.ametys.core.user.UserIdentity;
034import org.ametys.core.userpref.UserPreferencesException;
035import org.ametys.core.userpref.UserPreferencesManager;
036import org.ametys.plugins.repository.AmetysObjectResolver;
037import org.ametys.web.repository.page.Page;
038import org.ametys.web.repository.page.ZoneItem;
039import org.ametys.web.userpref.FOUserPreferencesConstants;
040
041/**
042 * Create or set user preferences attached to a link directory service or the link directory input data mode for front-end users
043 */
044public class LinkDirectorySetUserPreferencesAction extends ServiceableAction
045{
046    /** The user preferences manager. */
047    private UserPreferencesManager _userPrefManager;
048
049    /** The ametys object resolver */
050    private AmetysObjectResolver _resolver;
051    
052    /** The current user provider */
053    private CurrentUserProvider _currentUserProvider;
054    
055    
056    @Override
057    public void service(ServiceManager serviceManager) throws ServiceException
058    {
059        super.service(serviceManager);
060        _userPrefManager = (UserPreferencesManager) serviceManager.lookup(UserPreferencesManager.ROLE + ".FO");
061        _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
062        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
063    }
064    
065    @Override
066    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
067    {
068        Map<String, Object> result = new HashMap<>();
069        Request request = ObjectModelHelper.getRequest(objectModel);
070        
071        // We save user preferences for the FO or BO users
072        UserIdentity user = _currentUserProvider.getUser();
073        if (user != null && StringUtils.isNotEmpty(user.getLogin()) && StringUtils.isNotEmpty(user.getPopulationId()))
074        {
075            String zoneItemId = request.getParameter("zone-item-id");
076            ZoneItem zoneItem = _resolver.resolveById(zoneItemId);
077            Page page = zoneItem.getZone().getPage();
078            String siteName = page.getSiteName();
079            String language = page.getSitemapName();
080            
081            String storageContext = _getStorageContext(siteName, language, zoneItemId);
082            Map<String, String> contextVars = _getContextVars(siteName, language);
083            
084            _setLinksPositionUserPref(request, storageContext, contextVars, user);
085            _setHiddenLinksUserPref(request, storageContext, contextVars, user);
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 context with the language and the site name 
107     * @param siteName the name of the site
108     * @param language the language
109     * @return the context map
110     */
111    private Map<String, String> _getContextVars(String siteName, String language)
112    {
113        Map<String, String> contextVars = new HashMap<>();
114        
115        contextVars.put(FOUserPreferencesConstants.CONTEXT_VAR_SITENAME, siteName);
116        contextVars.put(FOUserPreferencesConstants.CONTEXT_VAR_LANGUAGE, language);
117        
118        return contextVars;
119    }
120    
121    /**
122     * Set the links position user pref
123     * @param request the request
124     * @param storageContext the storage context
125     * @param contextVars the context vars
126     * @param user the current user
127     * @throws UserPreferencesException If failed to save user preferences
128     */
129    private void _setLinksPositionUserPref(Request request, String storageContext, Map<String, String> contextVars, UserIdentity user) throws UserPreferencesException
130    {
131        String linksPosition = _getLinksPosition(request);
132        
133        // If null, we don't change the user pref.
134        // However, if empty, we set to empty the user pref. 
135        if (linksPosition != null)  
136        {
137            // TODO it would be nice to change the name of this user pref but the storage is still the same, so for the moment we avoid the SQL migration
138            // Cf issue LINKS-141
139            // Change in org.ametys.plugins.linkdirectory.DirectoryHelper#saxLinks too
140            
141            _userPrefManager.addUserPreference(user, storageContext, contextVars, "checked-links", linksPosition);
142        }
143        
144    }
145    
146    /**
147     * Get the ordered link ids from the request
148     * @param request the request
149     * @return the comma-separated string of ordered links ids
150     */
151    private String _getLinksPosition(Request request)
152    {
153        return request.getParameter("ordered-links");
154    }
155    
156    /**
157     * Set the hidden links user pref
158     * @param request the request
159     * @param storageContext the storage context
160     * @param contextVars the context vars
161     * @param user the current user
162     * @throws UserPreferencesException if failed to save user preferences
163     */
164    private void _setHiddenLinksUserPref(Request request, String storageContext, Map<String, String> contextVars, UserIdentity user) throws UserPreferencesException
165    {
166        String hiddenLinks = _getHiddenLinks(request);
167        
168        // If null, we don't change the user pref.
169        // However, if empty, we set to empty the user pref. 
170        if (hiddenLinks != null)  
171        {
172            _userPrefManager.addUserPreference(user, storageContext, contextVars, "hidden-links", hiddenLinks);
173        }
174        
175    }
176    
177    /**
178     * Get the hidden link ids from the request
179     * @param request the request
180     * @return the comma-separated string of hidden links ids
181     */
182    private String _getHiddenLinks(Request request)
183    {
184        return request.getParameter("hidden-links");
185    }
186}