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.model;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.ParamUtil;
022    import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
023    import com.liferay.portal.kernel.util.ProxyUtil;
024    import com.liferay.portal.kernel.util.ReflectionUtil;
025    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
026    import com.liferay.portal.service.ServiceContext;
027    import com.liferay.portal.service.ServiceContextThreadLocal;
028    
029    import java.io.Serializable;
030    
031    import java.lang.reflect.InvocationHandler;
032    import java.lang.reflect.InvocationTargetException;
033    import java.lang.reflect.Method;
034    
035    import java.util.HashSet;
036    import java.util.Set;
037    
038    /**
039     * @author Julio Camarero
040     * @author Brian Wing Shun Chan
041     */
042    public class LayoutSetStagingHandler
043            implements InvocationHandler, Serializable {
044    
045            public LayoutSetStagingHandler(LayoutSet layoutSet) {
046                    _layoutSet = layoutSet;
047    
048                    try {
049                            _layoutSetBranch = _getLayoutSetBranch(layoutSet);
050                    }
051                    catch (Exception e) {
052                            _log.error(e, e);
053    
054                            throw new IllegalStateException(e);
055                    }
056            }
057    
058            public LayoutSet getLayoutSet() {
059                    return _layoutSet;
060            }
061    
062            public LayoutSetBranch getLayoutSetBranch() {
063                    return _layoutSetBranch;
064            }
065    
066            @Override
067            public Object invoke(Object proxy, Method method, Object[] arguments)
068                    throws Throwable {
069    
070                    try {
071                            if (_layoutSetBranch == null) {
072                                    return method.invoke(_layoutSet, arguments);
073                            }
074    
075                            String methodName = method.getName();
076    
077                            if (methodName.equals("toEscapedModel")) {
078                                    if (_layoutSet.isEscapedModel()) {
079                                            return this;
080                                    }
081    
082                                    return _toEscapedModel();
083                            }
084    
085                            if (methodName.equals("clone")) {
086                                    return _clone();
087                            }
088    
089                            Object bean = _layoutSet;
090    
091                            if (_layoutSetBranchMethodNames.contains(methodName)) {
092                                    try {
093                                            Class<?> layoutSetBranchClass = _layoutSetBranch.getClass();
094    
095                                            method = layoutSetBranchClass.getMethod(
096                                                    methodName,
097                                                    ReflectionUtil.getParameterTypes(arguments));
098    
099                                            bean = _layoutSetBranch;
100                                    }
101                                    catch (NoSuchMethodException nsme) {
102                                            _log.error(nsme, nsme);
103                                    }
104                            }
105    
106                            return method.invoke(bean, arguments);
107                    }
108                    catch (InvocationTargetException ite) {
109                            throw ite.getTargetException();
110                    }
111            }
112    
113            public void setLayoutSetBranch(LayoutSetBranch layoutSetBranch) {
114                    _layoutSetBranch = layoutSetBranch;
115            }
116    
117            private Object _clone() {
118                    return ProxyUtil.newProxyInstance(
119                            PortalClassLoaderUtil.getClassLoader(), new Class[] {Layout.class},
120                            new LayoutSetStagingHandler(_layoutSet));
121            }
122    
123            private LayoutSetBranch _getLayoutSetBranch(LayoutSet layoutSet)
124                    throws PortalException, SystemException {
125    
126                    ServiceContext serviceContext =
127                            ServiceContextThreadLocal.getServiceContext();
128    
129                    if (serviceContext == null) {
130                            return null;
131                    }
132    
133                    long layoutSetBranchId = ParamUtil.getLong(
134                            serviceContext, "layoutSetBranchId");
135    
136                    LayoutSetBranch layoutSetBranch = null;
137    
138                    if (serviceContext.isSignedIn()) {
139                            layoutSetBranch =
140                                    LayoutSetBranchLocalServiceUtil.getUserLayoutSetBranch(
141                                            serviceContext.getUserId(), layoutSet.getGroupId(),
142                                            layoutSet.isPrivateLayout(), layoutSet.getLayoutSetId(),
143                                            layoutSetBranchId);
144                    }
145                    else if (layoutSetBranchId > 0) {
146                            layoutSetBranch =
147                                    LayoutSetBranchLocalServiceUtil.getLayoutSetBranch(
148                                            layoutSetBranchId);
149                    }
150    
151                    return layoutSetBranch;
152            }
153    
154            private Object _toEscapedModel() {
155                    return ProxyUtil.newProxyInstance(
156                            PortalClassLoaderUtil.getClassLoader(), new Class[] {Layout.class},
157                            new LayoutSetStagingHandler(_layoutSet.toEscapedModel()));
158            }
159    
160            private static Log _log = LogFactoryUtil.getLog(
161                    LayoutSetStagingHandler.class);
162    
163            private static Set<String> _layoutSetBranchMethodNames =
164                    new HashSet<String>();
165    
166            static {
167                    _layoutSetBranchMethodNames.add("getColorScheme");
168                    _layoutSetBranchMethodNames.add("getColorSchemeId");
169                    _layoutSetBranchMethodNames.add("getCss");
170                    _layoutSetBranchMethodNames.add("getLayoutSetPrototypeLinkEnabled");
171                    _layoutSetBranchMethodNames.add("getLayoutSetPrototypeUuid");
172                    _layoutSetBranchMethodNames.add("getLogo");
173                    _layoutSetBranchMethodNames.add("getLogoId");
174                    _layoutSetBranchMethodNames.add("getSettings");
175                    _layoutSetBranchMethodNames.add("getTheme");
176                    _layoutSetBranchMethodNames.add("getThemeId");
177                    _layoutSetBranchMethodNames.add("getWapColorScheme");
178                    _layoutSetBranchMethodNames.add("getWapColorSchemeId");
179                    _layoutSetBranchMethodNames.add("getWapTheme");
180                    _layoutSetBranchMethodNames.add("getWapThemeId");
181                    _layoutSetBranchMethodNames.add("getSettingsProperties");
182                    _layoutSetBranchMethodNames.add("getSettings");
183                    _layoutSetBranchMethodNames.add("getStagingLogoId");
184                    _layoutSetBranchMethodNames.add("getThemeSetting");
185                    _layoutSetBranchMethodNames.add("getSettingsProperty");
186                    _layoutSetBranchMethodNames.add("isLayoutSetPrototypeLinkActive");
187                    _layoutSetBranchMethodNames.add("isEscapedModel");
188                    _layoutSetBranchMethodNames.add("isLogo");
189                    _layoutSetBranchMethodNames.add("setColorSchemeId");
190                    _layoutSetBranchMethodNames.add("setCss");
191                    _layoutSetBranchMethodNames.add("setLayoutSetPrototypeLinkEnabled");
192                    _layoutSetBranchMethodNames.add("setLayoutSetPrototypeUuid");
193                    _layoutSetBranchMethodNames.add("setEscapedModel");
194                    _layoutSetBranchMethodNames.add("setLogo");
195                    _layoutSetBranchMethodNames.add("setLogoId");
196                    _layoutSetBranchMethodNames.add("setSettings");
197                    _layoutSetBranchMethodNames.add("setSettingsProperties");
198                    _layoutSetBranchMethodNames.add("setThemeId");
199                    _layoutSetBranchMethodNames.add("setWapColorSchemeId");
200                    _layoutSetBranchMethodNames.add("setWapThemeId");
201            }
202    
203            private LayoutSet _layoutSet;
204            private LayoutSetBranch _layoutSetBranch;
205    
206    }