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