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.cluster;
016    
017    import com.liferay.portal.bean.IdentifiableBeanInvokerUtil;
018    import com.liferay.portal.kernel.cluster.ClusterInvokeAcceptor;
019    import com.liferay.portal.kernel.cluster.ClusterableContextThreadLocal;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.GroupThreadLocal;
022    import com.liferay.portal.kernel.util.InstanceFactory;
023    import com.liferay.portal.kernel.util.LocaleThreadLocal;
024    import com.liferay.portal.kernel.util.MethodHandler;
025    import com.liferay.portal.kernel.util.MethodKey;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.User;
028    import com.liferay.portal.security.auth.CompanyThreadLocal;
029    import com.liferay.portal.security.auth.PrincipalThreadLocal;
030    import com.liferay.portal.security.permission.PermissionChecker;
031    import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
032    import com.liferay.portal.security.permission.PermissionThreadLocal;
033    import com.liferay.portal.service.UserLocalServiceUtil;
034    
035    import java.io.Serializable;
036    
037    import java.util.Locale;
038    import java.util.Map;
039    
040    import org.aopalliance.intercept.MethodInvocation;
041    
042    /**
043     * @author Shuyang Zhou
044     */
045    public class ClusterableInvokerUtil {
046    
047            public static MethodHandler createMethodHandler(
048                    Class<? extends ClusterInvokeAcceptor> clusterInvokeAcceptorClass,
049                    MethodInvocation methodInvocation) {
050    
051                    MethodHandler methodHandler =
052                            IdentifiableBeanInvokerUtil.createMethodHandler(methodInvocation);
053    
054                    Map<String, Serializable> context =
055                            ClusterableContextThreadLocal.collectThreadLocalContext();
056    
057                    _populateContextFromThreadLocals(context);
058    
059                    String clusterInvokeAcceptorClassName =
060                            clusterInvokeAcceptorClass.getName();
061    
062                    if (clusterInvokeAcceptorClass == ClusterInvokeAcceptor.class) {
063                            clusterInvokeAcceptorClassName = null;
064                    }
065    
066                    return new MethodHandler(
067                            _invokeMethodKey, methodHandler, clusterInvokeAcceptorClassName,
068                            context);
069            }
070    
071            @SuppressWarnings("unused")
072            private static Object _invoke(
073                            MethodHandler methodHandler, String clusterInvokeAcceptorClassName,
074                            Map<String, Serializable> context)
075                    throws Exception {
076    
077                    if (Validator.isNotNull(clusterInvokeAcceptorClassName)) {
078                            ClusterInvokeAcceptor clusterInvokeAcceptor =
079                                    (ClusterInvokeAcceptor)InstanceFactory.newInstance(
080                                            clusterInvokeAcceptorClassName);
081    
082                            if (!clusterInvokeAcceptor.accept(context)) {
083                                    return null;
084                            }
085                    }
086    
087                    _populateThreadLocalsFromContext(context);
088    
089                    return methodHandler.invoke();
090            }
091    
092            private static void _populateContextFromThreadLocals(
093                    Map<String, Serializable> context) {
094    
095                    if (!context.containsKey("companyId")) {
096                            context.put("companyId", CompanyThreadLocal.getCompanyId());
097                    }
098    
099                    if (!context.containsKey("defaultLocale")) {
100                            context.put("defaultLocale", LocaleThreadLocal.getDefaultLocale());
101                    }
102    
103                    if (!context.containsKey("groupId")) {
104                            context.put("groupId", GroupThreadLocal.getGroupId());
105                    }
106    
107                    if (!context.containsKey("principalName")) {
108                            context.put("principalName", PrincipalThreadLocal.getName());
109                    }
110    
111                    if (!context.containsKey("principalPassword")) {
112                            context.put(
113                                    "principalPassword", PrincipalThreadLocal.getPassword());
114                    }
115    
116                    if (!context.containsKey("siteDefaultLocale")) {
117                            context.put(
118                                    "siteDefaultLocale", LocaleThreadLocal.getSiteDefaultLocale());
119                    }
120    
121                    if (!context.containsKey("themeDisplayLocale")) {
122                            context.put(
123                                    "themeDisplayLocale",
124                                    LocaleThreadLocal.getThemeDisplayLocale());
125                    }
126            }
127    
128            private static void _populateThreadLocalsFromContext(
129                    Map<String, Serializable> context) {
130    
131                    long companyId = GetterUtil.getLong(context.get("companyId"));
132    
133                    if (companyId > 0) {
134                            CompanyThreadLocal.setCompanyId(companyId);
135                    }
136    
137                    Locale defaultLocale = (Locale)context.get("defaultLocale");
138    
139                    if (defaultLocale != null) {
140                            LocaleThreadLocal.setDefaultLocale(defaultLocale);
141                    }
142    
143                    long groupId = GetterUtil.getLong(context.get("groupId"));
144    
145                    if (groupId > 0) {
146                            GroupThreadLocal.setGroupId(groupId);
147                    }
148    
149                    String principalName = GetterUtil.getString(
150                            context.get("principalName"));
151    
152                    if (Validator.isNotNull(principalName)) {
153                            PrincipalThreadLocal.setName(principalName);
154                    }
155    
156                    PermissionChecker permissionChecker = null;
157    
158                    if (Validator.isNotNull(principalName)) {
159                            try {
160                                    User user = UserLocalServiceUtil.fetchUser(
161                                            PrincipalThreadLocal.getUserId());
162    
163                                    permissionChecker = PermissionCheckerFactoryUtil.create(user);
164                            }
165                            catch (Exception e) {
166                                    throw new RuntimeException(e);
167                            }
168                    }
169    
170                    if (permissionChecker != null) {
171                            PermissionThreadLocal.setPermissionChecker(permissionChecker);
172                    }
173    
174                    String principalPassword = GetterUtil.getString(
175                            context.get("principalPassword"));
176    
177                    if (Validator.isNotNull(principalPassword)) {
178                            PrincipalThreadLocal.setPassword(principalPassword);
179                    }
180    
181                    Locale siteDefaultLocale = (Locale)context.get("siteDefaultLocale");
182    
183                    if (siteDefaultLocale != null) {
184                            LocaleThreadLocal.setSiteDefaultLocale(siteDefaultLocale);
185                    }
186    
187                    Locale themeDisplayLocale = (Locale)context.get("themeDisplayLocale");
188    
189                    if (themeDisplayLocale != null) {
190                            LocaleThreadLocal.setThemeDisplayLocale(themeDisplayLocale);
191                    }
192            }
193    
194            private static final MethodKey _invokeMethodKey = new MethodKey(
195                    ClusterableInvokerUtil.class, "_invoke", MethodHandler.class,
196                    String.class, Map.class);
197    
198    }