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.portal.service.impl;
016    
017    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
018    import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
019    import com.liferay.portal.kernel.staging.StagingUtil;
020    import com.liferay.portal.kernel.util.ParamUtil;
021    import com.liferay.portal.kernel.workflow.WorkflowConstants;
022    import com.liferay.portal.model.Layout;
023    import com.liferay.portal.model.LayoutConstants;
024    import com.liferay.portal.model.LayoutRevision;
025    import com.liferay.portal.model.PortletPreferencesIds;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.security.auth.PrincipalThreadLocal;
028    import com.liferay.portal.service.LayoutLocalServiceUtil;
029    import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
030    import com.liferay.portal.service.ServiceContext;
031    import com.liferay.portal.service.ServiceContextThreadLocal;
032    import com.liferay.portal.service.UserLocalServiceUtil;
033    import com.liferay.portal.service.persistence.LayoutRevisionUtil;
034    import com.liferay.portal.staging.ProxiedLayoutsThreadLocal;
035    import com.liferay.portal.staging.StagingAdvicesThreadLocal;
036    
037    import java.lang.reflect.InvocationTargetException;
038    import java.lang.reflect.Method;
039    
040    import org.aopalliance.intercept.MethodInterceptor;
041    import org.aopalliance.intercept.MethodInvocation;
042    
043    /**
044     * @author Raymond Aug??
045     */
046    public class PortletPreferencesLocalServiceStagingAdvice
047            implements MethodInterceptor {
048    
049            @Override
050            public Object invoke(MethodInvocation methodInvocation) throws Throwable {
051                    if (!StagingAdvicesThreadLocal.isEnabled()) {
052                            return methodInvocation.proceed();
053                    }
054    
055                    try {
056                            Object[] arguments = methodInvocation.getArguments();
057    
058                            if (arguments == null) {
059                                    return methodInvocation.proceed();
060                            }
061    
062                            Method method = methodInvocation.getMethod();
063    
064                            String methodName = method.getName();
065    
066                            if (methodName.equals("getPortletPreferences") &&
067                                    ((arguments.length == 3) || (arguments.length == 4))) {
068    
069                                    return getPortletPreferences(methodInvocation);
070                            }
071                            else if (methodName.equals("getPortletPreferencesCount") &&
072                                             ((arguments.length == 3) || (arguments.length == 5))) {
073    
074                                    return getPortletPreferencesCount(methodInvocation);
075                            }
076                            else if (methodName.equals("getPreferences")) {
077                                    return getPreferences(methodInvocation);
078                            }
079                            else if (methodName.equals("getStrictPreferences")) {
080                                    return getPreferences(methodInvocation);
081                            }
082                            else if (methodName.equals("updatePreferences")) {
083                                    return updatePreferences(methodInvocation);
084                            }
085    
086                            return methodInvocation.proceed();
087                    }
088                    catch (InvocationTargetException ite) {
089                            throw ite.getCause();
090                    }
091                    catch (Throwable throwable) {
092                            throw throwable;
093                    }
094            }
095    
096            protected Object getPortletPreferences(MethodInvocation methodInvocation)
097                    throws Throwable {
098    
099                    Method method = methodInvocation.getMethod();
100                    Object[] arguments = methodInvocation.getArguments();
101    
102                    long plid = 0;
103    
104                    if (((arguments.length == 3) || (arguments.length == 4)) &&
105                            (arguments[2] instanceof Long)) {
106    
107                            plid = (Long)arguments[2];
108                    }
109    
110                    if (plid <= 0) {
111                            return methodInvocation.proceed();
112                    }
113    
114                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
115    
116                    if (!LayoutStagingUtil.isBranchingLayout(layout)) {
117                            return methodInvocation.proceed();
118                    }
119    
120                    LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
121                            layout);
122    
123                    arguments[2] = layoutRevision.getLayoutRevisionId();
124    
125                    return method.invoke(methodInvocation.getThis(), arguments);
126            }
127    
128            protected Object getPortletPreferencesCount(
129                            MethodInvocation methodInvocation)
130                    throws Throwable {
131    
132                    Method method = methodInvocation.getMethod();
133                    Object[] arguments = methodInvocation.getArguments();
134    
135                    long plid = LayoutConstants.DEFAULT_PLID;
136    
137                    if (arguments.length == 3) {
138                            plid = (Long)arguments[1];
139                    }
140                    else {
141                            plid = (Long)arguments[2];
142                    }
143    
144                    if (plid <= 0) {
145                            return methodInvocation.proceed();
146                    }
147    
148                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
149    
150                    if (layout == null) {
151                            return methodInvocation.proceed();
152                    }
153    
154                    if (!LayoutStagingUtil.isBranchingLayout(layout)) {
155                            return methodInvocation.proceed();
156                    }
157    
158                    LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
159                            layout);
160    
161                    if (arguments.length == 3) {
162                            arguments[1] = layoutRevision.getLayoutRevisionId();
163                    }
164                    else {
165                            arguments[2] = layoutRevision.getLayoutRevisionId();
166                    }
167    
168                    return method.invoke(methodInvocation.getThis(), arguments);
169            }
170    
171            protected Object getPreferences(MethodInvocation methodInvocation)
172                    throws Throwable {
173    
174                    Method method = methodInvocation.getMethod();
175                    Object[] arguments = methodInvocation.getArguments();
176    
177                    long plid = 0;
178    
179                    if (arguments.length == 1) {
180                            PortletPreferencesIds portletPreferencesIds =
181                                    (PortletPreferencesIds)arguments[0];
182    
183                            plid = portletPreferencesIds.getPlid();
184                    }
185                    else {
186                            plid = (Long)arguments[3];
187                    }
188    
189                    if (plid <= 0) {
190                            return methodInvocation.proceed();
191                    }
192    
193                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
194    
195                    if (!LayoutStagingUtil.isBranchingLayout(layout)) {
196                            return methodInvocation.proceed();
197                    }
198    
199                    LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
200                            layout);
201    
202                    if (layoutRevision == null) {
203                            return methodInvocation.proceed();
204                    }
205    
206                    User user = UserLocalServiceUtil.getUserById(
207                            PrincipalThreadLocal.getUserId());
208    
209                    plid = StagingUtil.getRecentLayoutRevisionId(
210                            user, layoutRevision.getLayoutSetBranchId(), layout.getPlid());
211    
212                    if (arguments.length == 1) {
213                            PortletPreferencesIds portletPreferencesIds =
214                                    (PortletPreferencesIds)arguments[0];
215    
216                            portletPreferencesIds.setPlid(plid);
217                    }
218                    else {
219                            arguments[3] = plid;
220                    }
221    
222                    return method.invoke(methodInvocation.getThis(), arguments);
223            }
224    
225            protected Object updatePreferences(MethodInvocation methodInvocation)
226                    throws Throwable {
227    
228                    Method method = methodInvocation.getMethod();
229                    Object[] arguments = methodInvocation.getArguments();
230    
231                    long plid = (Long)arguments[2];
232    
233                    if (plid <= 0) {
234                            return methodInvocation.proceed();
235                    }
236    
237                    LayoutRevision layoutRevision = LayoutRevisionUtil.fetchByPrimaryKey(
238                            plid);
239    
240                    ServiceContext serviceContext =
241                            ServiceContextThreadLocal.getServiceContext();
242    
243                    if (serviceContext == null) {
244                            return methodInvocation.proceed();
245                    }
246    
247                    boolean exporting = ParamUtil.getBoolean(serviceContext, "exporting");
248    
249                    if ((layoutRevision == null) || exporting) {
250                            return methodInvocation.proceed();
251                    }
252    
253                    if (!MergeLayoutPrototypesThreadLocal.isInProgress()) {
254                            serviceContext.setWorkflowAction(
255                                    WorkflowConstants.ACTION_SAVE_DRAFT);
256                    }
257    
258                    layoutRevision = LayoutRevisionLocalServiceUtil.updateLayoutRevision(
259                            serviceContext.getUserId(), layoutRevision.getLayoutRevisionId(),
260                            layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
261                            layoutRevision.getTitle(), layoutRevision.getDescription(),
262                            layoutRevision.getKeywords(), layoutRevision.getRobots(),
263                            layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
264                            layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
265                            layoutRevision.getColorSchemeId(), layoutRevision.getWapThemeId(),
266                            layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
267                            serviceContext);
268    
269                    arguments[2] = layoutRevision.getLayoutRevisionId();
270    
271                    ProxiedLayoutsThreadLocal.clearProxiedLayouts();
272    
273                    return method.invoke(methodInvocation.getThis(), arguments);
274            }
275    
276    }