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.resiliency.service;
016    
017    import com.liferay.portal.kernel.bean.PortletBeanLocatorUtil;
018    import com.liferay.portal.kernel.process.ProcessCallable;
019    import com.liferay.portal.kernel.process.ProcessException;
020    import com.liferay.portal.kernel.util.MethodHandler;
021    import com.liferay.portal.model.User;
022    import com.liferay.portal.security.auth.PrincipalThreadLocal;
023    import com.liferay.portal.security.permission.PermissionChecker;
024    import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
025    import com.liferay.portal.security.permission.PermissionThreadLocal;
026    import com.liferay.portal.service.UserLocalServiceUtil;
027    
028    import java.io.Externalizable;
029    import java.io.IOException;
030    import java.io.ObjectInput;
031    import java.io.ObjectOutput;
032    import java.io.Serializable;
033    
034    /**
035     * @author Shuyang Zhou
036     */
037    public class ServiceMethodProcessCallable
038            implements Externalizable, ProcessCallable<Serializable> {
039    
040            /**
041             * The empty constructor is required by {@link java.io.Externalizable}. Do
042             * not use this for any other purpose.
043             */
044            public ServiceMethodProcessCallable() {
045            }
046    
047            public ServiceMethodProcessCallable(
048                    String servletContextName, String beanIdentifier,
049                    MethodHandler methodHandler) {
050    
051                    _servletContextName = servletContextName;
052                    _beanIdentifier = beanIdentifier;
053                    _methodHandler = methodHandler;
054    
055                    PermissionChecker permissionChecker =
056                            PermissionThreadLocal.getPermissionChecker();
057    
058                    if (permissionChecker != null) {
059                            _userId = permissionChecker.getUserId();
060                    }
061            }
062    
063            @Override
064            public Serializable call() throws ProcessException {
065                    String oldName = PrincipalThreadLocal.getName();
066                    PermissionChecker oldPermissionChecker =
067                            PermissionThreadLocal.getPermissionChecker();
068    
069                    try {
070                            if (_userId != 0) {
071                                    PrincipalThreadLocal.setName(_userId);
072    
073                                    User user = UserLocalServiceUtil.fetchUser(_userId);
074    
075                                    if (user != null) {
076                                            PermissionChecker permissionChecker =
077                                                    PermissionCheckerFactoryUtil.create(user);
078    
079                                            PermissionThreadLocal.setPermissionChecker(
080                                                    permissionChecker);
081                                    }
082                            }
083    
084                            Object bean = PortletBeanLocatorUtil.locate(
085                                    _servletContextName, _beanIdentifier);
086    
087                            return (Serializable)_methodHandler.invoke(bean);
088                    }
089                    catch (Exception e) {
090                            throw new ProcessException(e);
091                    }
092                    finally {
093                            PrincipalThreadLocal.setName(oldName);
094                            PermissionThreadLocal.setPermissionChecker(oldPermissionChecker);
095                    }
096            }
097    
098            @Override
099            public void readExternal(ObjectInput objectInput)
100                    throws ClassNotFoundException, IOException {
101    
102                    _beanIdentifier = objectInput.readUTF();
103                    _methodHandler = (MethodHandler)objectInput.readObject();
104                    _servletContextName = objectInput.readUTF();
105                    _userId = objectInput.readLong();
106            }
107    
108            @Override
109            public void writeExternal(ObjectOutput objectOutput) throws IOException {
110                    objectOutput.writeUTF(_beanIdentifier);
111                    objectOutput.writeObject(_methodHandler);
112                    objectOutput.writeUTF(_servletContextName);
113                    objectOutput.writeLong(_userId);
114            }
115    
116            private String _beanIdentifier;
117            private MethodHandler _methodHandler;
118            private String _servletContextName;
119            private long _userId;
120    
121    }