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.service;
016    
017    import com.liferay.portal.spring.aop.ChainableMethodAdvice;
018    
019    import java.lang.reflect.Method;
020    
021    import org.aopalliance.intercept.MethodInvocation;
022    
023    /**
024     * @author Preston Crary
025     */
026    public class ServiceContextAdvice extends ChainableMethodAdvice {
027    
028            @Override
029            public Object invoke(MethodInvocation methodInvocation) throws Throwable {
030                    if (!hasServiceContextParameter(methodInvocation.getMethod())) {
031                            serviceBeanAopCacheManager.removeMethodInterceptor(
032                                    methodInvocation, this);
033                    }
034    
035                    boolean pushedServiceContext = pushServiceContext(methodInvocation);
036    
037                    try {
038                            return methodInvocation.proceed();
039                    }
040                    finally {
041                            if (pushedServiceContext) {
042                                    ServiceContextThreadLocal.popServiceContext();
043                            }
044                    }
045            }
046    
047            protected boolean hasServiceContextParameter(Method method) {
048                    Class<?>[] parameterTypes = method.getParameterTypes();
049    
050                    for (int i = parameterTypes.length - 1; i >= 0; i--) {
051                            if (ServiceContext.class.isAssignableFrom(parameterTypes[i])) {
052                                    return true;
053                            }
054                    }
055    
056                    return false;
057            }
058    
059            protected boolean pushServiceContext(MethodInvocation methodInvocation) {
060                    Object[] arguments = methodInvocation.getArguments();
061    
062                    if (arguments == null) {
063                            return false;
064                    }
065    
066                    for (int i = arguments.length - 1; i >= 0; i--) {
067                            if (arguments[i] instanceof ServiceContext) {
068                                    ServiceContext serviceContext = (ServiceContext)arguments[i];
069    
070                                    ServiceContextThreadLocal.pushServiceContext(serviceContext);
071    
072                                    return true;
073                            }
074                    }
075    
076                    return false;
077            }
078    
079    }