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.exportimport.kernel.staging.LayoutStagingUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.model.Group;
020    import com.liferay.portal.kernel.model.LayoutSet;
021    import com.liferay.portal.kernel.model.LayoutSetBranch;
022    import com.liferay.portal.kernel.model.LayoutSetStagingHandler;
023    import com.liferay.portal.kernel.service.LayoutSetLocalService;
024    import com.liferay.portal.kernel.util.ArrayUtil;
025    import com.liferay.portal.kernel.util.ClassLoaderUtil;
026    import com.liferay.portal.kernel.util.ColorSchemeFactoryUtil;
027    import com.liferay.portal.kernel.util.PortalUtil;
028    import com.liferay.portal.kernel.util.ProxyUtil;
029    import com.liferay.portal.kernel.util.ThemeFactoryUtil;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portlet.exportimport.staging.StagingAdvicesThreadLocal;
032    
033    import java.lang.reflect.InvocationTargetException;
034    import java.lang.reflect.Method;
035    
036    import java.util.ArrayList;
037    import java.util.Date;
038    import java.util.HashSet;
039    import java.util.List;
040    import java.util.Set;
041    
042    import org.aopalliance.intercept.MethodInterceptor;
043    import org.aopalliance.intercept.MethodInvocation;
044    
045    /**
046     * @author Julio Camarero
047     * @author Brian Wing Shun Chan
048     * @author Raymond Augé
049     */
050    public class LayoutSetLocalServiceStagingAdvice
051            extends LayoutSetLocalServiceImpl implements MethodInterceptor {
052    
053            @Override
054            public Object invoke(MethodInvocation methodInvocation) throws Throwable {
055                    if (!StagingAdvicesThreadLocal.isEnabled()) {
056                            return methodInvocation.proceed();
057                    }
058    
059                    Method method = methodInvocation.getMethod();
060    
061                    String methodName = method.getName();
062    
063                    if (!_layoutSetLocalServiceStagingAdviceMethodNames.contains(
064                                    methodName)) {
065    
066                            return wrapReturnValue(methodInvocation.proceed());
067                    }
068    
069                    Object returnValue = null;
070    
071                    Object thisObject = methodInvocation.getThis();
072                    Object[] arguments = methodInvocation.getArguments();
073    
074                    if (methodName.equals("updateLayoutSetPrototypeLinkEnabled") &&
075                            (arguments.length == 5)) {
076    
077                            updateLayoutSetPrototypeLinkEnabled(
078                                    (LayoutSetLocalService)thisObject, (Long)arguments[0],
079                                    (Boolean)arguments[1], (Boolean)arguments[2],
080                                    (String)arguments[3]);
081                    }
082                    else if (methodName.equals("updateLogo") && (arguments.length == 4)) {
083                            returnValue = updateLogo(
084                                    (LayoutSetLocalService)thisObject, (Long)arguments[0],
085                                    (Boolean)arguments[1], (Boolean)arguments[2],
086                                    (byte[])arguments[3]);
087                    }
088                    else if (methodName.equals("updateLookAndFeel") &&
089                                     (arguments.length == 5)) {
090    
091                            returnValue = updateLookAndFeel(
092                                    (LayoutSetLocalService)thisObject, (Long)arguments[0],
093                                    (Boolean)arguments[1], (String)arguments[2],
094                                    (String)arguments[3], (String)arguments[4]);
095                    }
096                    else if (methodName.equals("updateSettings")) {
097                            returnValue = updateSettings(
098                                    (LayoutSetLocalService)thisObject, (Long)arguments[0],
099                                    (Boolean)arguments[1], (String)arguments[2]);
100                    }
101                    else {
102                            try {
103                                    Class<?> clazz = getClass();
104    
105                                    Class<?>[] parameterTypes = ArrayUtil.append(
106                                            new Class<?>[] {LayoutSetLocalService.class},
107                                            method.getParameterTypes());
108    
109                                    Method layoutSetLocalServiceStagingAdviceMethod =
110                                            clazz.getMethod(methodName, parameterTypes);
111    
112                                    arguments = ArrayUtil.append(
113                                            new Object[] {thisObject}, arguments);
114    
115                                    returnValue = layoutSetLocalServiceStagingAdviceMethod.invoke(
116                                            this, arguments);
117                            }
118                            catch (InvocationTargetException ite) {
119                                    throw ite.getTargetException();
120                            }
121                            catch (NoSuchMethodException nsme) {
122                                    returnValue = methodInvocation.proceed();
123                            }
124                    }
125    
126                    return wrapReturnValue(returnValue);
127            }
128    
129            public void updateLayoutSetPrototypeLinkEnabled(
130                            LayoutSetLocalService layoutSetLocalService, long groupId,
131                            boolean privateLayout, boolean layoutSetPrototypeLinkEnabled,
132                            String layoutSetPrototypeUuid)
133                    throws PortalException {
134    
135                    LayoutSet layoutSet = layoutSetPersistence.findByG_P(
136                            groupId, privateLayout);
137    
138                    layoutSet = wrapLayoutSet(layoutSet);
139    
140                    LayoutSetBranch layoutSetBranch = LayoutStagingUtil.getLayoutSetBranch(
141                            layoutSet);
142    
143                    if (layoutSetBranch == null) {
144                            layoutSetLocalService.updateLayoutSetPrototypeLinkEnabled(
145                                    groupId, privateLayout, layoutSetPrototypeLinkEnabled,
146                                    layoutSetPrototypeUuid);
147    
148                            return;
149                    }
150    
151                    if (Validator.isNull(layoutSetPrototypeUuid)) {
152                            layoutSetPrototypeUuid =
153                                    layoutSetBranch.getLayoutSetPrototypeUuid();
154                    }
155    
156                    if (Validator.isNull(layoutSetPrototypeUuid) &&
157                            layoutSetPrototypeLinkEnabled) {
158    
159                            throw new IllegalStateException(
160                                    "Cannot set layoutSetPrototypeLinkEnabled to true when " +
161                                            "layoutSetPrototypeUuid is null");
162                    }
163    
164                    layoutSetBranch.setLayoutSetPrototypeLinkEnabled(
165                            layoutSetPrototypeLinkEnabled);
166                    layoutSetBranch.setLayoutSetPrototypeUuid(layoutSetPrototypeUuid);
167    
168                    layoutSetBranchPersistence.update(layoutSetBranch);
169            }
170    
171            public LayoutSet updateLogo(
172                            LayoutSetLocalService layoutSetLocalService, long groupId,
173                            boolean privateLayout, boolean logo, byte[] logoBytes)
174                    throws PortalException {
175    
176                    LayoutSet layoutSet = layoutSetPersistence.findByG_P(
177                            groupId, privateLayout);
178    
179                    layoutSet = wrapLayoutSet(layoutSet);
180    
181                    LayoutSetBranch layoutSetBranch = LayoutStagingUtil.getLayoutSetBranch(
182                            layoutSet);
183    
184                    if (layoutSetBranch == null) {
185                            return layoutSetLocalService.updateLogo(
186                                    groupId, privateLayout, logo, logoBytes);
187                    }
188    
189                    layoutSetBranch.setModifiedDate(new Date());
190    
191                    PortalUtil.updateImageId(
192                            layoutSetBranch, logo, logoBytes, "logoId", 0, 0, 0);
193    
194                    layoutSetBranchPersistence.update(layoutSetBranch);
195    
196                    return layoutSet;
197            }
198    
199            public LayoutSet updateLookAndFeel(
200                            LayoutSetLocalService target, long groupId, boolean privateLayout,
201                            String themeId, String colorSchemeId, String css)
202                    throws PortalException {
203    
204                    LayoutSet layoutSet = layoutSetPersistence.findByG_P(
205                            groupId, privateLayout);
206    
207                    layoutSet = wrapLayoutSet(layoutSet);
208    
209                    LayoutSetBranch layoutSetBranch = LayoutStagingUtil.getLayoutSetBranch(
210                            layoutSet);
211    
212                    if (layoutSetBranch == null) {
213                            return target.updateLookAndFeel(
214                                    groupId, privateLayout, themeId, colorSchemeId, css);
215                    }
216    
217                    layoutSetBranch.setModifiedDate(new Date());
218    
219                    if (Validator.isNull(themeId)) {
220                            themeId = ThemeFactoryUtil.getDefaultRegularThemeId(
221                                    layoutSetBranch.getCompanyId());
222                    }
223    
224                    if (Validator.isNull(colorSchemeId)) {
225                            colorSchemeId =
226                                    ColorSchemeFactoryUtil.getDefaultRegularColorSchemeId();
227                    }
228    
229                    layoutSetBranch.setThemeId(themeId);
230                    layoutSetBranch.setColorSchemeId(colorSchemeId);
231                    layoutSetBranch.setCss(css);
232    
233                    layoutSetBranchPersistence.update(layoutSetBranch);
234    
235                    return layoutSet;
236            }
237    
238            public LayoutSet updateSettings(
239                            LayoutSetLocalService target, long groupId, boolean privateLayout,
240                            String settings)
241                    throws PortalException {
242    
243                    LayoutSet layoutSet = layoutSetPersistence.findByG_P(
244                            groupId, privateLayout);
245    
246                    layoutSet = wrapLayoutSet(layoutSet);
247    
248                    LayoutSetBranch layoutSetBranch = LayoutStagingUtil.getLayoutSetBranch(
249                            layoutSet);
250    
251                    if (layoutSetBranch == null) {
252                            return target.updateSettings(groupId, privateLayout, settings);
253                    }
254    
255                    layoutSetBranch.setModifiedDate(new Date());
256                    layoutSetBranch.setSettings(settings);
257    
258                    layoutSetBranchPersistence.update(layoutSetBranch);
259    
260                    return layoutSet;
261            }
262    
263            protected LayoutSet unwrapLayoutSet(LayoutSet layoutSet) {
264                    LayoutSetStagingHandler layoutSetStagingHandler =
265                            LayoutStagingUtil.getLayoutSetStagingHandler(layoutSet);
266    
267                    if (layoutSetStagingHandler == null) {
268                            return layoutSet;
269                    }
270    
271                    return layoutSetStagingHandler.getLayoutSet();
272            }
273    
274            protected LayoutSet wrapLayoutSet(LayoutSet layoutSet) {
275                    LayoutSetStagingHandler layoutSetStagingHandler =
276                            LayoutStagingUtil.getLayoutSetStagingHandler(layoutSet);
277    
278                    if (layoutSetStagingHandler != null) {
279                            return layoutSet;
280                    }
281    
282                    Group group = null;
283    
284                    try {
285                            group = layoutSet.getGroup();
286                    }
287                    catch (Exception e) {
288                            return layoutSet;
289                    }
290    
291                    if (!LayoutStagingUtil.isBranchingLayoutSet(
292                                    group, layoutSet.getPrivateLayout())) {
293    
294                            return layoutSet;
295                    }
296    
297                    return (LayoutSet)ProxyUtil.newProxyInstance(
298                            ClassLoaderUtil.getPortalClassLoader(),
299                            new Class[] {LayoutSet.class},
300                            new LayoutSetStagingHandler(layoutSet));
301            }
302    
303            protected List<LayoutSet> wrapLayoutSets(List<LayoutSet> layoutSets) {
304                    if (layoutSets.isEmpty()) {
305                            return layoutSets;
306                    }
307    
308                    List<LayoutSet> wrappedLayoutSets = new ArrayList<>(layoutSets.size());
309    
310                    for (int i = 0; i < layoutSets.size(); i++) {
311                            LayoutSet wrappedLayoutSet = wrapLayoutSet(layoutSets.get(i));
312    
313                            wrappedLayoutSets.add(wrappedLayoutSet);
314                    }
315    
316                    return wrappedLayoutSets;
317            }
318    
319            protected Object wrapReturnValue(Object returnValue) {
320                    if (returnValue instanceof LayoutSet) {
321                            returnValue = wrapLayoutSet((LayoutSet)returnValue);
322                    }
323                    else if (returnValue instanceof List<?>) {
324                            List<?> list = (List<?>)returnValue;
325    
326                            if (!list.isEmpty() && (list.get(0) instanceof LayoutSet)) {
327                                    returnValue = wrapLayoutSets((List<LayoutSet>)returnValue);
328                            }
329                    }
330    
331                    return returnValue;
332            }
333    
334            private static final Set<String>
335                    _layoutSetLocalServiceStagingAdviceMethodNames = new HashSet<>();
336    
337            static {
338                    _layoutSetLocalServiceStagingAdviceMethodNames.add(
339                            "updateLayoutSetPrototypeLinkEnabled");
340                    _layoutSetLocalServiceStagingAdviceMethodNames.add("updateLogo");
341                    _layoutSetLocalServiceStagingAdviceMethodNames.add("updateLookAndFeel");
342                    _layoutSetLocalServiceStagingAdviceMethodNames.add("updateSettings");
343            }
344    
345    }