001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.cluster;
016    
017    import com.liferay.portal.kernel.cluster.ClusterExecutorUtil;
018    import com.liferay.portal.kernel.cluster.ClusterRequest;
019    import com.liferay.portal.kernel.cluster.Clusterable;
020    import com.liferay.portal.kernel.util.MethodHandler;
021    import com.liferay.portal.kernel.util.MethodTargetClassKey;
022    import com.liferay.portal.spring.aop.AnnotationChainableMethodAdvice;
023    
024    import java.lang.annotation.Annotation;
025    import java.lang.reflect.Method;
026    
027    import org.aopalliance.intercept.MethodInvocation;
028    
029    /**
030     * @author Shuyang Zhou
031     */
032    public class ClusterableAdvice
033            extends AnnotationChainableMethodAdvice<Clusterable> {
034    
035            public void afterReturning(MethodInvocation methodInvocation, Object result)
036                    throws Throwable {
037    
038                    if (!ClusterInvokeThreadLocal.isEnabled()) {
039                            return;
040                    }
041    
042                    MethodTargetClassKey methodTargetClassKey = buildMethodTargetClassKey(
043                            methodInvocation);
044    
045                    Clusterable clusterable = findAnnotation(methodTargetClassKey);
046    
047                    if (clusterable == _nullClusterable) {
048                            return;
049                    }
050    
051                    Method method = methodTargetClassKey.getMethod();
052    
053                    Method utilClassMethod = _getUtilClassMethod(method);
054    
055                    MethodHandler methodHandler = new MethodHandler(
056                            utilClassMethod, methodInvocation.getArguments());
057    
058                    ClusterRequest clusterRequest = ClusterRequest.createMulticastRequest(
059                            methodHandler, true);
060    
061                    clusterRequest.setServletContextName(_servletContextName);
062    
063                    ClusterExecutorUtil.execute(clusterRequest);
064            }
065    
066            public Clusterable getNullAnnotation() {
067                    return _nullClusterable;
068            }
069    
070            public void setServletContextName(String servletContextName) {
071                    _servletContextName = servletContextName;
072            }
073    
074            private Method _getUtilClassMethod(Method method) throws Exception {
075                    Thread currentThread = Thread.currentThread();
076    
077                    ClassLoader contextClassLoader = currentThread.getContextClassLoader();
078    
079                    Class<?> declaringClass = method.getDeclaringClass();
080    
081                    String utilClassName = declaringClass.getName().concat("Util");
082    
083                    Class<?> utilClass = contextClassLoader.loadClass(utilClassName);
084    
085                    return utilClass.getMethod(
086                            method.getName(), method.getParameterTypes());
087            }
088    
089            private static Clusterable _nullClusterable =
090                    new Clusterable() {
091    
092                            public Class<? extends Annotation> annotationType() {
093                                    return Clusterable.class;
094                            }
095    
096                    };
097    
098            private String _servletContextName;
099    
100    }