001    /**
002     * Copyright (c) 2000-2012 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.journalcontent.action;
016    
017    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
018    import com.liferay.portal.kernel.portlet.DefaultConfigurationAction;
019    import com.liferay.portal.kernel.portlet.PortletLayoutListener;
020    import com.liferay.portal.kernel.servlet.SessionErrors;
021    import com.liferay.portal.kernel.transaction.Isolation;
022    import com.liferay.portal.kernel.transaction.Propagation;
023    import com.liferay.portal.kernel.transaction.Transactional;
024    import com.liferay.portal.kernel.util.ParamUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.Layout;
028    import com.liferay.portal.model.Portlet;
029    import com.liferay.portal.service.PortletLocalServiceUtil;
030    import com.liferay.portal.spring.aop.ServiceBeanMethodInvocation;
031    import com.liferay.portal.theme.ThemeDisplay;
032    import com.liferay.portal.util.WebKeys;
033    import com.liferay.portlet.PortletPreferencesFactoryUtil;
034    
035    import java.lang.reflect.Method;
036    
037    import java.util.ArrayList;
038    import java.util.List;
039    
040    import javax.portlet.ActionRequest;
041    import javax.portlet.ActionResponse;
042    import javax.portlet.PortletConfig;
043    import javax.portlet.PortletPreferences;
044    import javax.portlet.PortletRequest;
045    
046    import org.aopalliance.intercept.MethodInterceptor;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     * @author Douglas Wong
051     * @author Raymond Augé
052     */
053    public class ConfigurationActionImpl extends DefaultConfigurationAction {
054    
055            @Override
056            public void processAction(
057                            PortletConfig portletConfig, ActionRequest actionRequest,
058                            ActionResponse actionResponse)
059                    throws Exception {
060    
061                    // This logic has to run in a transaction which we will invoke directly
062                    // since this is not a Spring bean
063    
064                    Method doProcessActionMethod = getDoProcessActionMethod();
065    
066                    ServiceBeanMethodInvocation serviceBeanMethodInvocation =
067                            new ServiceBeanMethodInvocation(
068                                    this, ConfigurationActionImpl.class, doProcessActionMethod,
069                                    new Object[] {portletConfig, actionRequest, actionResponse});
070    
071                    List<MethodInterceptor> methodInterceptors = getMethodInterceptors();
072    
073                    serviceBeanMethodInvocation.setMethodInterceptors(methodInterceptors);
074    
075                    try {
076                            serviceBeanMethodInvocation.proceed();
077                    }
078                    catch (Throwable t) {
079                            throw new Exception(t);
080                    }
081            }
082    
083            /**
084             * This method is invoked in a transaction because we may result in a
085             * persistence call before and/or after the call to super.processAction()
086             * which itself results in a persistence call.
087             */
088            @Transactional(
089                    isolation = Isolation.PORTAL, propagation = Propagation.REQUIRES_NEW,
090                    rollbackFor = {Exception.class}
091            )
092            protected void doProcessAction(
093                            PortletConfig portletConfig, ActionRequest actionRequest,
094                            ActionResponse actionResponse)
095                    throws Exception {
096    
097                    String[] extensions = actionRequest.getParameterValues("extensions");
098    
099                    setPreference(actionRequest, "extensions", extensions);
100    
101                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
102                            WebKeys.THEME_DISPLAY);
103    
104                    Layout layout = themeDisplay.getLayout();
105    
106                    String portletResource = ParamUtil.getString(
107                            actionRequest, "portletResource");
108    
109                    PortletPreferences preferences =
110                            PortletPreferencesFactoryUtil.getPortletSetup(
111                                    layout, portletResource, StringPool.BLANK);
112    
113                    String articleId = getArticleId(actionRequest);
114    
115                    String originalArticleId = preferences.getValue("articleId", null);
116    
117                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
118                            themeDisplay.getCompanyId(), portletResource);
119    
120                    PortletLayoutListener portletLayoutListener =
121                            portlet.getPortletLayoutListenerInstance();
122    
123                    if ((portletLayoutListener != null) &&
124                            Validator.isNotNull(originalArticleId) &&
125                            !originalArticleId.equals(articleId)) {
126    
127                            // Results in a persistence call
128    
129                            portletLayoutListener.onRemoveFromLayout(
130                                    portletResource, layout.getPlid());
131                    }
132    
133                    // Results in a persistence call
134    
135                    super.processAction(portletConfig, actionRequest, actionResponse);
136    
137                    if (SessionErrors.isEmpty(actionRequest) &&
138                            (portletLayoutListener != null)) {
139    
140                            // Results in a persistence call
141    
142                            portletLayoutListener.onAddToLayout(
143                                    portletResource, layout.getPlid());
144                    }
145            }
146    
147            protected String getArticleId(PortletRequest portletRequest) {
148                    String articleId = getParameter(portletRequest, "articleId");
149    
150                    return articleId.toUpperCase();
151            }
152    
153            protected Method getDoProcessActionMethod() {
154                    if (_doProcessActionMethod != null) {
155                            return _doProcessActionMethod;
156                    }
157    
158                    Class<?> clazz = getClass();
159    
160                    try {
161                            _doProcessActionMethod = clazz.getDeclaredMethod(
162                                    "doProcessAction",
163                                    new Class<?>[] {
164                                            PortletConfig.class, ActionRequest.class,
165                                            ActionResponse.class});
166                    }
167                    catch (Exception e) {
168                            throw new IllegalStateException(e);
169                    }
170    
171                    return _doProcessActionMethod;
172            }
173    
174            protected List<MethodInterceptor> getMethodInterceptors() {
175                    if (_methodInterceptors != null) {
176                            return _methodInterceptors;
177                    }
178    
179                    List<MethodInterceptor> methodInterceptors =
180                            new ArrayList<MethodInterceptor>();
181    
182                    MethodInterceptor methodInterceptor =
183                            (MethodInterceptor)PortalBeanLocatorUtil.locate(
184                                    "transactionAdvice");
185    
186                    methodInterceptors.add(methodInterceptor);
187    
188                    _methodInterceptors = methodInterceptors;
189    
190                    return _methodInterceptors;
191            }
192    
193            private Method _doProcessActionMethod;
194            private List<MethodInterceptor> _methodInterceptors;
195    
196    }