001    /**
002     * Copyright (c) 2000-2013 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.portlet.assetpublisher.action;
016    
017    import com.liferay.portal.kernel.json.JSONArray;
018    import com.liferay.portal.kernel.json.JSONFactoryUtil;
019    import com.liferay.portal.kernel.json.JSONObject;
020    import com.liferay.portal.kernel.portlet.DefaultConfigurationAction;
021    import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
022    import com.liferay.portal.kernel.portlet.PortletResponseUtil;
023    import com.liferay.portal.kernel.servlet.SessionErrors;
024    import com.liferay.portal.kernel.servlet.SessionMessages;
025    import com.liferay.portal.kernel.util.ArrayUtil;
026    import com.liferay.portal.kernel.util.Constants;
027    import com.liferay.portal.kernel.util.ContentTypes;
028    import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.ParamUtil;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.StringUtil;
033    import com.liferay.portal.kernel.util.UnicodeProperties;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.model.GroupConstants;
036    import com.liferay.portal.model.Layout;
037    import com.liferay.portal.model.LayoutTypePortletConstants;
038    import com.liferay.portal.security.auth.PrincipalException;
039    import com.liferay.portal.service.LayoutLocalServiceUtil;
040    import com.liferay.portal.service.ServiceContext;
041    import com.liferay.portal.service.ServiceContextFactory;
042    import com.liferay.portal.theme.ThemeDisplay;
043    import com.liferay.portal.util.PortalUtil;
044    import com.liferay.portal.util.WebKeys;
045    import com.liferay.portlet.PortletPreferencesFactoryUtil;
046    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
047    import com.liferay.portlet.asset.AssetTagException;
048    import com.liferay.portlet.asset.model.AssetRendererFactory;
049    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
050    import com.liferay.portlet.assetpublisher.util.AssetPublisher;
051    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
052    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
053    import com.liferay.portlet.dynamicdatamapping.storage.Field;
054    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
055    import com.liferay.portlet.dynamicdatamapping.util.DDMImpl;
056    import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
057    
058    import java.io.Serializable;
059    
060    import java.text.DateFormat;
061    
062    import java.util.Date;
063    import java.util.Map;
064    
065    import javax.portlet.ActionRequest;
066    import javax.portlet.ActionResponse;
067    import javax.portlet.PortletConfig;
068    import javax.portlet.PortletPreferences;
069    import javax.portlet.ResourceRequest;
070    import javax.portlet.ResourceResponse;
071    
072    /**
073     * @author Brian Wing Shun Chan
074     * @author Juan Fernández
075     */
076    public class ConfigurationActionImpl extends DefaultConfigurationAction {
077    
078            @Override
079            public void processAction(
080                            PortletConfig portletConfig, ActionRequest actionRequest,
081                            ActionResponse actionResponse)
082                    throws Exception {
083    
084                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
085    
086                    String portletResource = ParamUtil.getString(
087                            actionRequest, "portletResource");
088    
089                    PortletPreferences preferences =
090                            PortletPreferencesFactoryUtil.getPortletSetup(
091                                    actionRequest, portletResource);
092    
093                    if (cmd.equals(Constants.TRANSLATE)) {
094                            super.processAction(portletConfig, actionRequest, actionResponse);
095                    }
096                    else if (cmd.equals(Constants.UPDATE)) {
097                            validateEmailAssetEntryAdded(actionRequest);
098                            validateEmailFrom(actionRequest);
099    
100                            updateDisplaySettings(actionRequest);
101    
102                            String selectionStyle = getParameter(
103                                    actionRequest, "selectionStyle");
104    
105                            if (selectionStyle.equals("dynamic")) {
106                                    updateQueryLogic(actionRequest, preferences);
107                            }
108    
109                            updateDefaultAssetPublisher(actionRequest);
110    
111                            super.processAction(portletConfig, actionRequest, actionResponse);
112                    }
113                    else {
114                            try {
115                                    if (cmd.equals("add-scope")) {
116                                            addScope(actionRequest, preferences);
117                                    }
118                                    else if (cmd.equals("add-selection")) {
119                                            AssetPublisherUtil.addSelection(
120                                                    actionRequest, preferences, portletResource);
121                                    }
122                                    else if (cmd.equals("move-selection-down")) {
123                                            moveSelectionDown(actionRequest, preferences);
124                                    }
125                                    else if (cmd.equals("move-selection-up")) {
126                                            moveSelectionUp(actionRequest, preferences);
127                                    }
128                                    else if (cmd.equals("remove-selection")) {
129                                            removeSelection(actionRequest, preferences);
130                                    }
131                                    else if (cmd.equals("remove-scope")) {
132                                            removeScope(actionRequest, preferences);
133                                    }
134                                    else if (cmd.equals("select-scope")) {
135                                            setScopes(actionRequest, preferences);
136                                    }
137                                    else if (cmd.equals("selection-style")) {
138                                            setSelectionStyle(actionRequest, preferences);
139                                    }
140    
141                                    if (SessionErrors.isEmpty(actionRequest)) {
142                                            preferences.store();
143    
144                                            LiferayPortletConfig liferayPortletConfig =
145                                                    (LiferayPortletConfig)portletConfig;
146    
147                                            SessionMessages.add(
148                                                    actionRequest,
149                                                    liferayPortletConfig.getPortletId() +
150                                                            SessionMessages.KEY_SUFFIX_REFRESH_PORTLET,
151                                                    portletResource);
152    
153                                            SessionMessages.add(
154                                                    actionRequest,
155                                                    liferayPortletConfig.getPortletId() +
156                                                            SessionMessages.KEY_SUFFIX_UPDATED_CONFIGURATION);
157                                    }
158    
159                                    String redirect = PortalUtil.escapeRedirect(
160                                            ParamUtil.getString(actionRequest, "redirect"));
161    
162                                    if (Validator.isNotNull(redirect)) {
163                                            actionResponse.sendRedirect(redirect);
164                                    }
165                            }
166                            catch (Exception e) {
167                                    if (e instanceof AssetTagException) {
168                                            SessionErrors.add(actionRequest, e.getClass(), e);
169                                    }
170                                    else {
171                                            throw e;
172                                    }
173                            }
174                    }
175            }
176    
177            @Override
178            public void serveResource(
179                            PortletConfig portletConfig, ResourceRequest resourceRequest,
180                            ResourceResponse resourceResponse)
181                    throws Exception {
182    
183                    ThemeDisplay themeDisplay = (ThemeDisplay)resourceRequest.getAttribute(
184                            WebKeys.THEME_DISPLAY);
185    
186                    String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
187    
188                    if (!cmd.equals("getFieldValue")) {
189                            return;
190                    }
191    
192                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
193                            resourceRequest);
194    
195                    long structureId = ParamUtil.getLong(resourceRequest, "structureId");
196    
197                    Fields fields = (Fields)serviceContext.getAttribute(
198                            Fields.class.getName() + structureId);
199    
200                    if (fields == null) {
201                            String fieldsNamespace = ParamUtil.getString(
202                                    resourceRequest, "fieldsNamespace");
203    
204                            fields = DDMUtil.getFields(
205                                    structureId, fieldsNamespace, serviceContext);
206                    }
207    
208                    String fieldName = ParamUtil.getString(resourceRequest, "name");
209    
210                    Field field = fields.get(fieldName);
211    
212                    Serializable fieldValue = field.getValue(themeDisplay.getLocale());
213    
214                    DDMStructure ddmStructure = field.getDDMStructure();
215    
216                    String type = ddmStructure.getFieldType(fieldName);
217    
218                    if (fieldValue instanceof Date) {
219                            Date valueDate = (Date)fieldValue;
220    
221                            DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
222                                    "yyyyMMddHHmmss");
223    
224                            fieldValue = dateFormat.format(valueDate);
225                    }
226                    else if (type.equals(DDMImpl.TYPE_RADIO) ||
227                                     type.equals(DDMImpl.TYPE_SELECT)) {
228    
229                            String valueString = String.valueOf(fieldValue);
230    
231                            JSONArray jsonArray = JSONFactoryUtil.createJSONArray(valueString);
232    
233                            String[] stringArray = ArrayUtil.toStringArray(jsonArray);
234    
235                            fieldValue = stringArray[0];
236                    }
237    
238                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
239    
240                    jsonObject.put("value", String.valueOf(fieldValue));
241    
242                    resourceResponse.setContentType(ContentTypes.APPLICATION_JSON);
243    
244                    PortletResponseUtil.write(resourceResponse, jsonObject.toString());
245            }
246    
247            protected void addScope(
248                            ActionRequest actionRequest, PortletPreferences preferences)
249                    throws Exception {
250    
251                    String[] scopeIds = preferences.getValues(
252                            "scopeIds",
253                            new String[] {
254                                    AssetPublisher.SCOPE_ID_GROUP_PREFIX + GroupConstants.DEFAULT
255                            });
256    
257                    String scopeId = ParamUtil.getString(actionRequest, "scopeId");
258    
259                    checkPermission(actionRequest, scopeId);
260    
261                    if (!ArrayUtil.contains(scopeIds, scopeId)) {
262                            scopeIds = ArrayUtil.append(scopeIds, scopeId);
263                    }
264    
265                    preferences.setValues("scopeIds", scopeIds);
266            }
267    
268            protected void checkPermission(ActionRequest actionRequest, String scopeId)
269                    throws Exception {
270    
271                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
272                            WebKeys.THEME_DISPLAY);
273    
274                    Layout layout = themeDisplay.getLayout();
275    
276                    if (!AssetPublisherUtil.isScopeIdSelectable(
277                                    themeDisplay.getPermissionChecker(), scopeId,
278                                    themeDisplay.getCompanyGroupId(), layout)) {
279    
280                            throw new PrincipalException();
281                    }
282            }
283    
284            protected String[] getClassTypeIds(
285                            ActionRequest actionRequest, String[] classNameIds)
286                    throws Exception {
287    
288                    String anyAssetTypeString = getParameter(actionRequest, "anyAssetType");
289    
290                    boolean anyAssetType = GetterUtil.getBoolean(anyAssetTypeString);
291    
292                    if (anyAssetType) {
293                            return null;
294                    }
295    
296                    long defaultAssetTypeId = GetterUtil.getLong(anyAssetTypeString);
297    
298                    if ((defaultAssetTypeId == 0) && (classNameIds.length == 1)) {
299                            defaultAssetTypeId = GetterUtil.getLong(classNameIds[0]);
300                    }
301    
302                    if (defaultAssetTypeId <= 0 ) {
303                            return null;
304                    }
305    
306                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
307                            WebKeys.THEME_DISPLAY);
308    
309                    String className = PortalUtil.getClassName(defaultAssetTypeId);
310    
311                    AssetRendererFactory assetRendererFactory =
312                            AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName(
313                                    className);
314    
315                    long[] groupIds = {
316                            themeDisplay.getCompanyGroupId(), themeDisplay.getSiteGroupId()
317                    };
318    
319                    Map<Long, String> classTypes = assetRendererFactory.getClassTypes(
320                            groupIds, themeDisplay.getLocale());
321    
322                    if (classTypes.isEmpty()) {
323                            return null;
324                    }
325    
326                    String assetClassName = AssetPublisherUtil.getClassName(
327                            assetRendererFactory);
328    
329                    String anyAssetClassTypeString = getParameter(
330                            actionRequest, "anyClassType" + assetClassName);
331    
332                    boolean anyAssetClassType = GetterUtil.getBoolean(
333                            anyAssetClassTypeString);
334    
335                    if (anyAssetClassType) {
336                            return null;
337                    }
338    
339                    long defaultAssetClassTypeId = GetterUtil.getLong(
340                            anyAssetClassTypeString);
341    
342                    if (defaultAssetClassTypeId > 0) {
343                            return new String[] {String.valueOf(defaultAssetClassTypeId)};
344                    }
345                    else {
346                            return StringUtil.split(
347                                    getParameter(actionRequest, "classTypeIds" + assetClassName));
348                    }
349            }
350    
351            protected void moveSelectionDown(
352                            ActionRequest actionRequest, PortletPreferences preferences)
353                    throws Exception {
354    
355                    int assetEntryOrder = ParamUtil.getInteger(
356                            actionRequest, "assetEntryOrder");
357    
358                    String[] manualEntries = preferences.getValues(
359                            "assetEntryXml", new String[0]);
360    
361                    if ((assetEntryOrder >= (manualEntries.length - 1)) ||
362                            (assetEntryOrder < 0)) {
363    
364                            return;
365                    }
366    
367                    String temp = manualEntries[assetEntryOrder + 1];
368    
369                    manualEntries[assetEntryOrder + 1] = manualEntries[assetEntryOrder];
370                    manualEntries[assetEntryOrder] = temp;
371    
372                    preferences.setValues("assetEntryXml", manualEntries);
373            }
374    
375            protected void moveSelectionUp(
376                            ActionRequest actionRequest, PortletPreferences preferences)
377                    throws Exception {
378    
379                    int assetEntryOrder = ParamUtil.getInteger(
380                            actionRequest, "assetEntryOrder");
381    
382                    String[] manualEntries = preferences.getValues(
383                            "assetEntryXml", new String[0]);
384    
385                    if ((assetEntryOrder >= manualEntries.length) ||
386                            (assetEntryOrder <= 0)) {
387    
388                            return;
389                    }
390    
391                    String temp = manualEntries[assetEntryOrder - 1];
392    
393                    manualEntries[assetEntryOrder - 1] = manualEntries[assetEntryOrder];
394                    manualEntries[assetEntryOrder] = temp;
395    
396                    preferences.setValues("assetEntryXml", manualEntries);
397            }
398    
399            protected void removeScope(
400                            ActionRequest actionRequest, PortletPreferences preferences)
401                    throws Exception {
402    
403                    String[] scopeIds = preferences.getValues(
404                            "scopeIds",
405                            new String[] {
406                                    AssetPublisher.SCOPE_ID_GROUP_PREFIX + GroupConstants.DEFAULT
407                            });
408    
409                    String scopeId = ParamUtil.getString(actionRequest, "scopeId");
410    
411                    scopeIds = ArrayUtil.remove(scopeIds, scopeId);
412    
413                    preferences.setValues("scopeIds", scopeIds);
414            }
415    
416            protected void removeSelection(
417                            ActionRequest actionRequest, PortletPreferences preferences)
418                    throws Exception {
419    
420                    int assetEntryOrder = ParamUtil.getInteger(
421                            actionRequest, "assetEntryOrder");
422    
423                    String[] manualEntries = preferences.getValues(
424                            "assetEntryXml", new String[0]);
425    
426                    if (assetEntryOrder >= manualEntries.length) {
427                            return;
428                    }
429    
430                    String[] newEntries = new String[manualEntries.length -1];
431    
432                    int i = 0;
433                    int j = 0;
434    
435                    for (; i < manualEntries.length; i++) {
436                            if (i != assetEntryOrder) {
437                                    newEntries[j++] = manualEntries[i];
438                            }
439                    }
440    
441                    preferences.setValues("assetEntryXml", newEntries);
442            }
443    
444            protected void setScopes(
445                            ActionRequest actionRequest, PortletPreferences preferences)
446                    throws Exception {
447    
448                    String[] scopeIds = StringUtil.split(
449                            getParameter(actionRequest, "scopeIds"));
450    
451                    preferences.setValues("scopeIds", scopeIds);
452            }
453    
454            protected void setSelectionStyle(
455                            ActionRequest actionRequest, PortletPreferences preferences)
456                    throws Exception {
457    
458                    String selectionStyle = getParameter(actionRequest, "selectionStyle");
459                    String displayStyle = getParameter(actionRequest, "displayStyle");
460    
461                    preferences.setValue("selectionStyle", selectionStyle);
462    
463                    if (selectionStyle.equals("manual") ||
464                            selectionStyle.equals("view-count")) {
465    
466                            preferences.setValue("enableRss", String.valueOf(false));
467                            preferences.setValue("showQueryLogic", Boolean.FALSE.toString());
468    
469                            preferences.reset("rssDelta");
470                            preferences.reset("rssDisplayStyle");
471                            preferences.reset("rssFormat");
472                            preferences.reset("rssName");
473                    }
474    
475                    if (!selectionStyle.equals("view-count") &&
476                            displayStyle.equals("view-count-details")) {
477    
478                            preferences.setValue("displayStyle", "full-content");
479                    }
480            }
481    
482            protected void updateDefaultAssetPublisher(ActionRequest actionRequest)
483                    throws Exception {
484    
485                    boolean defaultAssetPublisher = ParamUtil.getBoolean(
486                            actionRequest, "defaultAssetPublisher");
487    
488                    Layout layout = (Layout)actionRequest.getAttribute(WebKeys.LAYOUT);
489    
490                    String portletResource = ParamUtil.getString(
491                            actionRequest, "portletResource");
492    
493                    UnicodeProperties typeSettingsProperties =
494                            layout.getTypeSettingsProperties();
495    
496                    if (defaultAssetPublisher) {
497                            typeSettingsProperties.setProperty(
498                                    LayoutTypePortletConstants.DEFAULT_ASSET_PUBLISHER_PORTLET_ID,
499                                    portletResource);
500                    }
501                    else {
502                            String defaultAssetPublisherPortletId =
503                                    typeSettingsProperties.getProperty(
504                                            LayoutTypePortletConstants.
505                                                    DEFAULT_ASSET_PUBLISHER_PORTLET_ID);
506    
507                            if (Validator.isNotNull(defaultAssetPublisherPortletId) &&
508                                    defaultAssetPublisherPortletId.equals(portletResource)) {
509    
510                                    typeSettingsProperties.setProperty(
511                                            LayoutTypePortletConstants.
512                                                    DEFAULT_ASSET_PUBLISHER_PORTLET_ID,
513                                            StringPool.BLANK);
514                            }
515                    }
516    
517                    layout = LayoutLocalServiceUtil.updateLayout(
518                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
519                            layout.getTypeSettings());
520            }
521    
522            protected void updateDisplaySettings(ActionRequest actionRequest)
523                    throws Exception {
524    
525                    String[] classNameIds = StringUtil.split(
526                            getParameter(actionRequest, "classNameIds"));
527                    String[] classTypeIds = getClassTypeIds(actionRequest, classNameIds);
528                    String[] extensions = actionRequest.getParameterValues("extensions");
529    
530                    setPreference(actionRequest, "classNameIds", classNameIds);
531                    setPreference(actionRequest, "classTypeIds", classTypeIds);
532                    setPreference(actionRequest, "extensions", extensions);
533            }
534    
535            protected void updateQueryLogic(
536                            ActionRequest actionRequest, PortletPreferences preferences)
537                    throws Exception {
538    
539                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
540                            WebKeys.THEME_DISPLAY);
541    
542                    long userId = themeDisplay.getUserId();
543                    long groupId = themeDisplay.getSiteGroupId();
544    
545                    int[] queryRulesIndexes = StringUtil.split(
546                            ParamUtil.getString(actionRequest, "queryLogicIndexes"), 0);
547    
548                    int i = 0;
549    
550                    for (int queryRulesIndex : queryRulesIndexes) {
551                            boolean contains = ParamUtil.getBoolean(
552                                    actionRequest, "queryContains" + queryRulesIndex);
553                            boolean andOperator = ParamUtil.getBoolean(
554                                    actionRequest, "queryAndOperator" + queryRulesIndex);
555                            String name = ParamUtil.getString(
556                                    actionRequest, "queryName" + queryRulesIndex);
557    
558                            String[] values = null;
559    
560                            if (name.equals("assetTags")) {
561                                    values = StringUtil.split(
562                                            ParamUtil.getString(
563                                                    actionRequest, "queryTagNames" + queryRulesIndex));
564    
565                                    AssetTagLocalServiceUtil.checkTags(userId, groupId, values);
566                            }
567                            else {
568                                    values = StringUtil.split(
569                                            ParamUtil.getString(
570                                                    actionRequest, "queryCategoryIds" + queryRulesIndex));
571                            }
572    
573                            setPreference(
574                                    actionRequest, "queryContains" + i, String.valueOf(contains));
575                            setPreference(
576                                    actionRequest, "queryAndOperator" + i,
577                                    String.valueOf(andOperator));
578                            setPreference(actionRequest, "queryName" + i, name);
579                            setPreference(actionRequest, "queryValues" + i, values);
580    
581                            i++;
582                    }
583    
584                    // Clear previous preferences that are now blank
585    
586                    String[] values = preferences.getValues(
587                            "queryValues" + i, new String[0]);
588    
589                    while (values.length > 0) {
590                            setPreference(actionRequest, "queryContains" + i, StringPool.BLANK);
591                            setPreference(
592                                    actionRequest, "queryAndOperator" + i, StringPool.BLANK);
593                            setPreference(actionRequest, "queryName" + i, StringPool.BLANK);
594                            setPreference(actionRequest, "queryValues" + i, new String[0]);
595    
596                            i++;
597    
598                            values = preferences.getValues("queryValues" + i, new String[0]);
599                    }
600            }
601    
602            protected void validateEmailAssetEntryAdded(ActionRequest actionRequest)
603                    throws Exception {
604    
605                    String emailAssetEntryAddedSubject = getLocalizedParameter(
606                            actionRequest, "emailAssetEntryAddedSubject");
607                    String emailAssetEntryAddedBody = getLocalizedParameter(
608                            actionRequest, "emailAssetEntryAddedBody");
609    
610                    if (Validator.isNull(emailAssetEntryAddedSubject)) {
611                            SessionErrors.add(actionRequest, "emailAssetEntryAddedSubject");
612                    }
613                    else if (Validator.isNull(emailAssetEntryAddedBody)) {
614                            SessionErrors.add(actionRequest, "emailAssetEntryAddedBody");
615                    }
616            }
617    
618            protected void validateEmailFrom(ActionRequest actionRequest)
619                    throws Exception {
620    
621                    String emailFromName = getParameter(actionRequest, "emailFromName");
622                    String emailFromAddress = getParameter(
623                            actionRequest, "emailFromAddress");
624    
625                    if (Validator.isNull(emailFromName)) {
626                            SessionErrors.add(actionRequest, "emailFromName");
627                    }
628                    else if (!Validator.isEmailAddress(emailFromAddress) &&
629                                     !Validator.isVariableTerm(emailFromAddress)) {
630    
631                            SessionErrors.add(actionRequest, "emailFromAddress");
632                    }
633            }
634    
635    }