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