001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
019    import com.liferay.portal.kernel.staging.MergeLayoutPrototypesThreadLocal;
020    import com.liferay.portal.kernel.staging.StagingUtil;
021    import com.liferay.portal.kernel.util.ParamUtil;
022    import com.liferay.portal.kernel.workflow.WorkflowConstants;
023    import com.liferay.portal.model.Layout;
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 == 2) || (arguments.length == 3) ||
068                                     (arguments.length == 4))) {
069    
070                                    return getPortletPreferences(methodInvocation);
071                            }
072                            else if (methodName.equals("getPortletPreferencesCount") &&
073                                             ((arguments.length == 3) || (arguments.length == 5))) {
074    
075                                    return getPortletPreferencesCount(methodInvocation);
076                            }
077                            else if (methodName.equals("getPreferences")) {
078                                    return getPreferences(methodInvocation);
079                            }
080                            else if (methodName.equals("getStrictPreferences")) {
081                                    return getPreferences(methodInvocation);
082                            }
083                            else if (methodName.equals("updatePreferences")) {
084                                    return updatePreferences(methodInvocation);
085                            }
086    
087                            return methodInvocation.proceed();
088                    }
089                    catch (InvocationTargetException ite) {
090                            throw ite.getCause();
091                    }
092                    catch (Throwable throwable) {
093                            throw throwable;
094                    }
095            }
096    
097            protected LayoutRevision getLayoutRevision(long plid)
098                    throws SystemException {
099    
100                    if (plid <= 0) {
101                            return null;
102                    }
103    
104                    LayoutRevision layoutRevision = LayoutRevisionUtil.fetchByPrimaryKey(
105                            plid);
106    
107                    if (layoutRevision != null) {
108                            return layoutRevision;
109                    }
110    
111                    Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
112    
113                    if (layout == null) {
114                            return null;
115                    }
116    
117                    if (!LayoutStagingUtil.isBranchingLayout(layout)) {
118                            return null;
119                    }
120    
121                    return LayoutStagingUtil.getLayoutRevision(layout);
122            }
123    
124            protected Object getPortletPreferences(MethodInvocation methodInvocation)
125                    throws Throwable {
126    
127                    Method method = methodInvocation.getMethod();
128                    Object[] arguments = methodInvocation.getArguments();
129    
130                    int index = -1;
131    
132                    if ((arguments.length == 2) && (arguments[0] instanceof Long) &&
133                            (arguments[1] instanceof String)) {
134    
135                            index = 0;
136                    }
137                    else if ((arguments.length == 3) && (arguments[0] instanceof Integer) &&
138                                     (arguments[1] instanceof Long) &&
139                                     (arguments[2] instanceof String)) {
140    
141                            index = 1;
142                    }
143                    else if (((arguments.length == 3) || (arguments.length == 4)) &&
144                                     (arguments[2] instanceof Long)) {
145    
146                            index = 2;
147                    }
148    
149                    long plid = 0;
150    
151                    if (index >= 0) {
152                            plid = (Long)arguments[index];
153                    }
154    
155                    LayoutRevision layoutRevision = getLayoutRevision(plid);
156    
157                    if (layoutRevision == null) {
158                            return methodInvocation.proceed();
159                    }
160    
161                    arguments[index] = layoutRevision.getLayoutRevisionId();
162    
163                    return method.invoke(methodInvocation.getThis(), arguments);
164            }
165    
166            protected Object getPortletPreferencesCount(
167                            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 == 3) {
176                            plid = (Long)arguments[1];
177                    }
178                    else {
179                            plid = (Long)arguments[2];
180                    }
181    
182                    LayoutRevision layoutRevision = getLayoutRevision(plid);
183    
184                    if (layoutRevision == null) {
185                            return methodInvocation.proceed();
186                    }
187    
188                    if (arguments.length == 3) {
189                            arguments[1] = layoutRevision.getLayoutRevisionId();
190                    }
191                    else {
192                            arguments[2] = layoutRevision.getLayoutRevisionId();
193                    }
194    
195                    return method.invoke(methodInvocation.getThis(), arguments);
196            }
197    
198            protected Object getPreferences(MethodInvocation methodInvocation)
199                    throws Throwable {
200    
201                    Method method = methodInvocation.getMethod();
202                    Object[] arguments = methodInvocation.getArguments();
203    
204                    long plid = 0;
205    
206                    if (arguments.length == 1) {
207                            PortletPreferencesIds portletPreferencesIds =
208                                    (PortletPreferencesIds)arguments[0];
209    
210                            plid = portletPreferencesIds.getPlid();
211                    }
212                    else {
213                            plid = (Long)arguments[3];
214                    }
215    
216                    LayoutRevision layoutRevision = getLayoutRevision(plid);
217    
218                    if (layoutRevision == null) {
219                            return methodInvocation.proceed();
220                    }
221    
222                    User user = UserLocalServiceUtil.fetchUser(
223                            PrincipalThreadLocal.getUserId());
224    
225                    if ((user == null) || user.isDefaultUser()) {
226                            plid = layoutRevision.getLayoutRevisionId();
227                    }
228                    else {
229                            plid = StagingUtil.getRecentLayoutRevisionId(
230                                    user, layoutRevision.getLayoutSetBranchId(),
231                                    layoutRevision.getPlid());
232                    }
233    
234                    if (arguments.length == 1) {
235                            PortletPreferencesIds portletPreferencesIds =
236                                    (PortletPreferencesIds)arguments[0];
237    
238                            portletPreferencesIds.setPlid(plid);
239                    }
240                    else {
241                            arguments[3] = plid;
242                    }
243    
244                    return method.invoke(methodInvocation.getThis(), arguments);
245            }
246    
247            protected Object updatePreferences(MethodInvocation methodInvocation)
248                    throws Throwable {
249    
250                    Method method = methodInvocation.getMethod();
251                    Object[] arguments = methodInvocation.getArguments();
252    
253                    long plid = (Long)arguments[2];
254    
255                    LayoutRevision layoutRevision = getLayoutRevision(plid);
256    
257                    if (layoutRevision == null) {
258                            return methodInvocation.proceed();
259                    }
260    
261                    ServiceContext serviceContext =
262                            ServiceContextThreadLocal.getServiceContext();
263    
264                    if (serviceContext == null) {
265                            return methodInvocation.proceed();
266                    }
267    
268                    boolean exporting = ParamUtil.getBoolean(serviceContext, "exporting");
269    
270                    if (exporting) {
271                            return methodInvocation.proceed();
272                    }
273    
274                    if (!MergeLayoutPrototypesThreadLocal.isInProgress()) {
275                            serviceContext.setWorkflowAction(
276                                    WorkflowConstants.ACTION_SAVE_DRAFT);
277                    }
278    
279                    layoutRevision = LayoutRevisionLocalServiceUtil.updateLayoutRevision(
280                            serviceContext.getUserId(), layoutRevision.getLayoutRevisionId(),
281                            layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
282                            layoutRevision.getTitle(), layoutRevision.getDescription(),
283                            layoutRevision.getKeywords(), layoutRevision.getRobots(),
284                            layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
285                            layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
286                            layoutRevision.getColorSchemeId(), layoutRevision.getWapThemeId(),
287                            layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
288                            serviceContext);
289    
290                    arguments[2] = layoutRevision.getLayoutRevisionId();
291    
292                    ProxiedLayoutsThreadLocal.clearProxiedLayouts();
293    
294                    return method.invoke(methodInvocation.getThis(), arguments);
295            }
296    
297    }