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