001/*
002 *  Copyright 2012 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.core.userpref;
017
018import java.io.IOException;
019import java.util.Collections;
020import java.util.List;
021import java.util.Map;
022import java.util.Map.Entry;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.cocoon.ProcessingException;
027import org.apache.cocoon.environment.ObjectModelHelper;
028import org.apache.cocoon.environment.Request;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.apache.commons.lang.StringUtils;
032import org.xml.sax.SAXException;
033
034import org.ametys.core.user.UserIdentity;
035import org.ametys.core.userpref.UserPreference;
036import org.ametys.core.userpref.UserPreferencesException;
037import org.ametys.core.userpref.UserPreferencesExtensionPoint;
038import org.ametys.core.userpref.UserPreferencesManager;
039import org.ametys.core.util.cocoon.AbstractCurrentUserProviderServiceableGenerator;
040import org.ametys.runtime.i18n.I18nizableText;
041import org.ametys.runtime.parameter.Enumerator;
042import org.ametys.runtime.parameter.ParameterHelper;
043import org.ametys.runtime.parameter.Validator;
044
045/**
046 * Generates user preferences.
047 */
048public class UserPreferencesGenerator extends AbstractCurrentUserProviderServiceableGenerator
049{
050    
051    /** The user preferences extension point. */
052    protected UserPreferencesExtensionPoint _userPrefEP;
053    
054    /** The user preferences manager. */
055    protected UserPreferencesManager _userPrefManager;
056    
057    @Override
058    public void service(ServiceManager serviceManager) throws ServiceException
059    {
060        super.service(serviceManager);
061        _userPrefEP = (UserPreferencesExtensionPoint) serviceManager.lookup(UserPreferencesExtensionPoint.ROLE);
062        _userPrefManager = (UserPreferencesManager) serviceManager.lookup(UserPreferencesManager.ROLE);
063    }
064    
065    @Override
066    public void generate() throws IOException, SAXException, ProcessingException
067    {
068        Request request = ObjectModelHelper.getRequest(objectModel);
069        String storageContext = parameters.getParameter("prefContext", request.getParameter("prefContext"));
070        
071        boolean excludePrivate = parameters.getParameterAsBoolean("excludePrivate", false);
072        
073        Map<String, String> contextVars = getContextVars(request);
074        UserIdentity user = getUser();
075        
076        if (StringUtils.isBlank(storageContext))
077        {
078            throw new ProcessingException("Preferences context can't be blank");
079        }
080        
081        try
082        {
083            contentHandler.startDocument();
084            
085            if (user != null)
086            {
087                AttributesImpl atts = new AttributesImpl();
088                atts.addCDATAAttribute("username", user.getLogin());
089                atts.addCDATAAttribute("userpopulation", user.getPopulationId());
090                atts.addCDATAAttribute("context", storageContext);
091                XMLUtils.startElement(contentHandler, "UserPreferences", atts);
092                
093                _saxPreferences(storageContext, contextVars, user, excludePrivate);
094                
095                XMLUtils.endElement(contentHandler, "UserPreferences");
096            }
097            else
098            {
099                XMLUtils.createElement(contentHandler, "UserPreferences");
100            }
101            
102            contentHandler.endDocument();
103        }
104        catch (UserPreferencesException e)
105        {
106            getLogger().error("Cannot get user preferences.", e);
107            throw new ProcessingException("Cannot get user preferences.", e);
108        }
109    }
110    
111    /**
112     * Get the user in the user manager.
113     * @return the user .
114     */
115    protected UserIdentity getUser()
116    {
117        String login = parameters.getParameter("username", "");
118        String populationId = parameters.getParameter("populationId", "");
119        UserIdentity user;
120        if (StringUtils.isEmpty(login) || StringUtils.isEmpty(populationId))
121        {
122            user = _currentUserProvider.getUser();
123        }
124        else
125        {
126            user = new UserIdentity(login, populationId);
127        }
128        return user;
129    }
130    
131    /**
132     * Get the preferences context.
133     * @param request the request.
134     * @return the preferences context as a Map.
135     */
136    protected Map<String, String> getContextVars(Request request)
137    {
138        return Collections.emptyMap();
139    }
140    
141    /**
142     * Generate the list of user preferences for a given user and context.
143     * @param storageContext the preferences context.
144     * @param contextVars The context vars
145     * @param user the user.
146     * @param excludePrivate true to exclude private user preferences
147     * @throws ProcessingException if an error occurred
148     * @throws SAXException if an error occurred
149     * @throws UserPreferencesException if an error occurred
150     */
151    protected void _saxPreferences(String storageContext, Map<String, String> contextVars, UserIdentity user, boolean excludePrivate) throws ProcessingException, SAXException, UserPreferencesException
152    {
153        Map<I18nizableText, List<UserPreference>> groups = _userPrefEP.getCategorizedPreferences(contextVars);
154        Map<String, String> prefValues = _userPrefManager.getUnTypedUserPrefs(user, storageContext, contextVars);
155        
156        XMLUtils.startElement(contentHandler, "groups");
157        
158        for (Entry<I18nizableText, List<UserPreference>> groupEntry : groups.entrySet())
159        {
160            I18nizableText groupLabel = groupEntry.getKey();
161            List<UserPreference> groupPrefs = groupEntry.getValue();
162            
163            XMLUtils.startElement(contentHandler, "group");
164            groupLabel.toSAX(contentHandler, "label");
165            
166            XMLUtils.startElement(contentHandler, "preferences");
167            for (UserPreference preference : groupPrefs)
168            {
169                if (!excludePrivate || !preference.isPrivate())
170                {
171                    _saxPreference(preference, prefValues.get(preference.getId()), contextVars);
172                }
173                
174            }
175            XMLUtils.endElement(contentHandler, "preferences");
176            
177            XMLUtils.endElement(contentHandler, "group");
178        }
179        
180        XMLUtils.endElement(contentHandler, "groups");
181    }
182    
183    /**
184     * Generate a preference definition and value.
185     * @param preference The parameter to SAX
186     * @param value The parameter value. Can be null.
187     * @param contextVars The context vars
188     * @throws SAXException If an error occurred while SAXing
189     * @throws ProcessingException If an error occurred
190     */
191    protected void _saxPreference(UserPreference preference, Object value, Map<String, String> contextVars) throws SAXException, ProcessingException
192    {
193        AttributesImpl attr = new AttributesImpl();
194        attr.addCDATAAttribute("id", preference.getId());
195        attr.addCDATAAttribute("plugin", preference.getPluginName());
196        attr.addCDATAAttribute("order", Integer.toString(preference.getOrder()));
197        attr.addCDATAAttribute("type", ParameterHelper.typeToString(preference.getType()));
198        attr.addCDATAAttribute("multiple", Boolean.toString(preference.isMultiple()));
199        attr.addCDATAAttribute("private", Boolean.toString(preference.isPrivate()));
200        XMLUtils.startElement(contentHandler, "preference", attr);
201        
202        if (preference.getLabel() != null)
203        {
204            preference.getLabel().toSAX(contentHandler, "label");
205        }
206        if (preference.getDescription() != null)
207        {
208            preference.getDescription().toSAX(contentHandler, "description");
209        }
210        
211        Object defaultValue = preference.getDefaultValue();
212        
213        if (defaultValue != null)
214        {
215            XMLUtils.createElement(contentHandler, "defaultValue", ParameterHelper.valueToString(defaultValue));
216        }
217        
218        if (value != null)
219        {
220            XMLUtils.createElement(contentHandler, "value", ParameterHelper.valueToString(value));
221        }
222        else if (defaultValue != null)
223        {
224            XMLUtils.createElement(contentHandler, "value", ParameterHelper.valueToString(defaultValue));
225        }
226        
227        if (preference.getWidget() != null)
228        {
229            XMLUtils.createElement(contentHandler, "widget", preference.getWidget());
230        }
231        
232        Map<String, I18nizableText> widgetParameters = preference.getWidgetParameters();
233        if (widgetParameters != null && !widgetParameters.isEmpty())
234        {
235            XMLUtils.startElement(contentHandler, "widget-params");
236            for (String paramName : widgetParameters.keySet())
237            {
238                XMLUtils.startElement(contentHandler, paramName);
239                widgetParameters.get(paramName).toSAX(contentHandler);
240                XMLUtils.endElement(contentHandler, paramName);
241            }
242            XMLUtils.endElement(contentHandler, "widget-params");
243        }
244        
245        Enumerator enumerator = preference.getEnumerator();
246        if (enumerator != null)
247        {
248            ParameterHelper.toSAXEnumerator(contentHandler, enumerator);
249        }
250        
251        Validator validator = preference.getValidator();
252        if (validator != null)
253        {
254            ParameterHelper.toSAXValidator(contentHandler, validator);
255        }
256        
257        XMLUtils.endElement(contentHandler, "preference");
258    }
259    
260}