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