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