001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.portlet;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.model.Layout;
019    import com.liferay.portal.kernel.model.Portlet;
020    import com.liferay.portal.kernel.security.permission.ActionKeys;
021    import com.liferay.portal.kernel.service.PortletLocalServiceUtil;
022    import com.liferay.portal.kernel.service.permission.PortletPermissionUtil;
023    import com.liferay.portal.kernel.servlet.SessionErrors;
024    import com.liferay.portal.kernel.servlet.SessionMessages;
025    import com.liferay.portal.kernel.settings.CompanyServiceSettingsLocator;
026    import com.liferay.portal.kernel.settings.GroupServiceSettingsLocator;
027    import com.liferay.portal.kernel.settings.ModifiableSettings;
028    import com.liferay.portal.kernel.settings.PortletInstanceSettingsLocator;
029    import com.liferay.portal.kernel.settings.Settings;
030    import com.liferay.portal.kernel.settings.SettingsDescriptor;
031    import com.liferay.portal.kernel.settings.SettingsFactoryUtil;
032    import com.liferay.portal.kernel.theme.ThemeDisplay;
033    import com.liferay.portal.kernel.util.Constants;
034    import com.liferay.portal.kernel.util.GetterUtil;
035    import com.liferay.portal.kernel.util.LocaleUtil;
036    import com.liferay.portal.kernel.util.LocalizationUtil;
037    import com.liferay.portal.kernel.util.ParamUtil;
038    import com.liferay.portal.kernel.util.PortalUtil;
039    import com.liferay.portal.kernel.util.PropertiesParamUtil;
040    import com.liferay.portal.kernel.util.StringPool;
041    import com.liferay.portal.kernel.util.StringUtil;
042    import com.liferay.portal.kernel.util.UnicodeProperties;
043    import com.liferay.portal.kernel.util.Validator;
044    import com.liferay.portal.kernel.util.WebKeys;
045    
046    import java.util.HashMap;
047    import java.util.Map;
048    import java.util.Set;
049    
050    import javax.portlet.ActionRequest;
051    import javax.portlet.ActionResponse;
052    import javax.portlet.PortletConfig;
053    import javax.portlet.PortletRequest;
054    import javax.portlet.ResourceRequest;
055    import javax.portlet.ResourceResponse;
056    import javax.portlet.ValidatorException;
057    
058    import javax.servlet.ServletContext;
059    import javax.servlet.http.HttpServletRequest;
060    
061    /**
062     * @author Iván Zaera
063     */
064    public abstract class SettingsConfigurationAction
065            extends LiferayPortlet
066            implements ConfigurationAction, ResourceServingConfigurationAction {
067    
068            public SettingsConfigurationAction() {
069                    setParameterNamePrefix("preferences--");
070            }
071    
072            public String getLocalizedParameter(
073                    PortletRequest portletRequest, String name) {
074    
075                    String languageId = ParamUtil.getString(portletRequest, "languageId");
076    
077                    return getLocalizedParameter(portletRequest, name, languageId);
078            }
079    
080            public String getLocalizedParameter(
081                    PortletRequest portletRequest, String name, String languageId) {
082    
083                    return getParameter(
084                            portletRequest,
085                            LocalizationUtil.getLocalizedName(name, languageId));
086            }
087    
088            public String getParameter(PortletRequest portletRequest, String name) {
089                    name = _parameterNamePrefix + name + StringPool.DOUBLE_DASH;
090    
091                    return ParamUtil.getString(portletRequest, name);
092            }
093    
094            @Override
095            public void processAction(
096                            PortletConfig portletConfig, ActionRequest actionRequest,
097                            ActionResponse actionResponse)
098                    throws Exception {
099    
100                    updateMultiValuedKeys(actionRequest);
101    
102                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
103    
104                    if (!cmd.equals(Constants.UPDATE)) {
105                            return;
106                    }
107    
108                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
109                            WebKeys.THEME_DISPLAY);
110    
111                    Layout layout = PortletConfigurationLayoutUtil.getLayout(themeDisplay);
112    
113                    String portletResource = ParamUtil.getString(
114                            actionRequest, "portletResource");
115    
116                    PortletPermissionUtil.check(
117                            themeDisplay.getPermissionChecker(), themeDisplay.getScopeGroupId(),
118                            layout, portletResource, ActionKeys.CONFIGURATION);
119    
120                    UnicodeProperties properties = PropertiesParamUtil.getProperties(
121                            actionRequest, _parameterNamePrefix);
122    
123                    Settings settings = getSettings(actionRequest);
124    
125                    ModifiableSettings modifiableSettings =
126                            settings.getModifiableSettings();
127    
128                    for (Map.Entry<String, String> entry : properties.entrySet()) {
129                            String name = entry.getKey();
130                            String value = entry.getValue();
131    
132                            String oldValue = settings.getValue(name, null);
133    
134                            if (!StringUtil.equalsIgnoreBreakLine(value, oldValue)) {
135                                    modifiableSettings.setValue(name, value);
136                            }
137                    }
138    
139                    Map<String, String[]> portletPreferencesMap =
140                            (Map<String, String[]>)actionRequest.getAttribute(
141                                    WebKeys.PORTLET_PREFERENCES_MAP);
142    
143                    if (portletPreferencesMap != null) {
144                            for (Map.Entry<String, String[]> entry :
145                                            portletPreferencesMap.entrySet()) {
146    
147                                    String name = entry.getKey();
148                                    String[] values = entry.getValue();
149    
150                                    String[] oldValues = settings.getValues(name, null);
151    
152                                    if (!Validator.equals(values, oldValues)) {
153                                            modifiableSettings.setValues(name, values);
154                                    }
155                            }
156                    }
157    
158                    postProcess(themeDisplay.getCompanyId(), actionRequest, settings);
159    
160                    if (SessionErrors.isEmpty(actionRequest)) {
161                            try {
162                                    modifiableSettings.store();
163                            }
164                            catch (ValidatorException ve) {
165                                    SessionErrors.add(
166                                            actionRequest, ValidatorException.class.getName(), ve);
167    
168                                    return;
169                            }
170    
171                            SessionMessages.add(
172                                    actionRequest,
173                                    PortalUtil.getPortletId(actionRequest) +
174                                            SessionMessages.KEY_SUFFIX_REFRESH_PORTLET,
175                                    portletResource);
176    
177                            SessionMessages.add(
178                                    actionRequest,
179                                    PortalUtil.getPortletId(actionRequest) +
180                                            SessionMessages.KEY_SUFFIX_UPDATED_CONFIGURATION);
181    
182                            String redirect = PortalUtil.escapeRedirect(
183                                    ParamUtil.getString(actionRequest, "redirect"));
184    
185                            if (Validator.isNotNull(redirect)) {
186                                    actionResponse.sendRedirect(redirect);
187                            }
188                    }
189            }
190    
191            @Override
192            public void serveResource(
193                            PortletConfig portletConfig, ResourceRequest resourceRequest,
194                            ResourceResponse resourceResponse)
195                    throws Exception {
196            }
197    
198            public void setPreference(
199                    PortletRequest portletRequest, String name, String value) {
200    
201                    setPreference(portletRequest, name, new String[] {value});
202            }
203    
204            public void setPreference(
205                    PortletRequest portletRequest, String name, String[] values) {
206    
207                    Map<String, String[]> portletPreferencesMap =
208                            (Map<String, String[]>)portletRequest.getAttribute(
209                                    WebKeys.PORTLET_PREFERENCES_MAP);
210    
211                    if (portletPreferencesMap == null) {
212                            portletPreferencesMap = new HashMap<>();
213    
214                            portletRequest.setAttribute(
215                                    WebKeys.PORTLET_PREFERENCES_MAP, portletPreferencesMap);
216                    }
217    
218                    portletPreferencesMap.put(name, values);
219            }
220    
221            protected PortletConfig getSelPortletConfig(HttpServletRequest request) {
222                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
223                            WebKeys.THEME_DISPLAY);
224    
225                    String portletResource = ParamUtil.getString(
226                            request, "portletResource");
227    
228                    Portlet selPortlet = PortletLocalServiceUtil.getPortletById(
229                            themeDisplay.getCompanyId(), portletResource);
230    
231                    ServletContext servletContext = (ServletContext)request.getAttribute(
232                            WebKeys.CTX);
233    
234                    PortletConfig selPortletConfig = PortletConfigFactoryUtil.create(
235                            selPortlet, servletContext);
236    
237                    return selPortletConfig;
238            }
239    
240            protected Settings getSettings(ActionRequest actionRequest)
241                    throws PortalException {
242    
243                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
244                            WebKeys.THEME_DISPLAY);
245    
246                    String serviceName = ParamUtil.getString(actionRequest, "serviceName");
247    
248                    String settingsScope = ParamUtil.getString(
249                            actionRequest, "settingsScope");
250    
251                    if (settingsScope.equals("company")) {
252                            return SettingsFactoryUtil.getSettings(
253                                    new CompanyServiceSettingsLocator(
254                                            themeDisplay.getCompanyId(), serviceName));
255                    }
256                    else if (settingsScope.equals("group")) {
257                            return SettingsFactoryUtil.getSettings(
258                                    new GroupServiceSettingsLocator(
259                                            themeDisplay.getSiteGroupId(), serviceName));
260                    }
261                    else if (settingsScope.equals("portletInstance")) {
262                            String portletResource = ParamUtil.getString(
263                                    actionRequest, "portletResource");
264    
265                            return SettingsFactoryUtil.getSettings(
266                                    new PortletInstanceSettingsLocator(
267                                            themeDisplay.getLayout(), portletResource));
268                    }
269    
270                    throw new IllegalArgumentException(
271                            "Invalid settings scope " + settingsScope);
272            }
273    
274            protected String getSettingsId(ActionRequest actionRequest) {
275                    String settingsId = ParamUtil.getString(actionRequest, "serviceName");
276    
277                    String settingsScope = ParamUtil.getString(
278                            actionRequest, "settingsScope");
279    
280                    if (settingsScope.equals("portletInstance")) {
281                            settingsId = ParamUtil.getString(actionRequest, "portletResource");
282                    }
283    
284                    return settingsId;
285            }
286    
287            @SuppressWarnings("unused")
288            protected void postProcess(
289                            long companyId, PortletRequest portletRequest, Settings settings)
290                    throws PortalException {
291            }
292    
293            protected void setParameterNamePrefix(String parameterNamePrefix) {
294                    _parameterNamePrefix = parameterNamePrefix;
295            }
296    
297            protected void updateMultiValuedKeys(ActionRequest actionRequest) {
298                    String settingsId = getSettingsId(actionRequest);
299    
300                    SettingsDescriptor settingsDescriptor =
301                            SettingsFactoryUtil.getSettingsDescriptor(settingsId);
302    
303                    Set<String> multiValuedKeys = settingsDescriptor.getMultiValuedKeys();
304    
305                    for (String multiValuedKey : multiValuedKeys) {
306                            String multiValuedValue = getParameter(
307                                    actionRequest, multiValuedKey);
308    
309                            if (multiValuedValue != null) {
310                                    setPreference(
311                                            actionRequest, multiValuedKey,
312                                            StringUtil.split(multiValuedValue));
313                            }
314                    }
315            }
316    
317            protected void validateEmail(
318                    ActionRequest actionRequest, String emailParam) {
319    
320                    boolean emailEnabled = GetterUtil.getBoolean(
321                            getParameter(actionRequest, emailParam + "Enabled"));
322                    String emailSubject = null;
323                    String emailBody = null;
324    
325                    String languageId = LocaleUtil.toLanguageId(
326                            LocaleUtil.getSiteDefault());
327    
328                    emailSubject = getLocalizedParameter(
329                            actionRequest, emailParam + "Subject", languageId);
330                    emailBody = getLocalizedParameter(
331                            actionRequest, emailParam + "Body", languageId);
332    
333                    if (emailEnabled) {
334                            if (Validator.isNull(emailSubject)) {
335                                    SessionErrors.add(actionRequest, emailParam + "Subject");
336                            }
337                            else if (Validator.isNull(emailBody)) {
338                                    SessionErrors.add(actionRequest, emailParam + "Body");
339                            }
340                    }
341            }
342    
343            protected void validateEmailFrom(ActionRequest actionRequest) {
344                    String emailFromName = getParameter(actionRequest, "emailFromName");
345                    String emailFromAddress = getParameter(
346                            actionRequest, "emailFromAddress");
347    
348                    if (Validator.isNull(emailFromName)) {
349                            SessionErrors.add(actionRequest, "emailFromName");
350                    }
351                    else if (!Validator.isEmailAddress(emailFromAddress) &&
352                                     !Validator.isVariableTerm(emailFromAddress)) {
353    
354                            SessionErrors.add(actionRequest, "emailFromAddress");
355                    }
356            }
357    
358            private String _parameterNamePrefix;
359    
360    }