001
014
015 package com.liferay.portal.kernel.cluster;
016
017 import com.liferay.portal.kernel.annotation.AnnotationLocator;
018 import com.liferay.portal.kernel.util.MethodKey;
019 import com.liferay.portal.kernel.util.ProxyUtil;
020
021 import java.lang.reflect.InvocationHandler;
022 import java.lang.reflect.Method;
023
024 import java.util.Map;
025 import java.util.concurrent.ConcurrentHashMap;
026
027
030 public class ClusterableProxyFactory {
031
032 public static <T> T createClusterableProxy(T targetObject) {
033 Class<?> targetClass = targetObject.getClass();
034
035 return (T)ProxyUtil.newProxyInstance(
036 targetClass.getClassLoader(), targetClass.getInterfaces(),
037 new ClusterableInvocationHandler<>(targetObject));
038 }
039
040 private static class ClusterableInvocationHandler<T>
041 implements InvocationHandler {
042
043 @Override
044 public Object invoke(Object proxy, Method method, Object[] arguments)
045 throws Throwable {
046
047 if (!ClusterInvokeThreadLocal.isEnabled()) {
048 return method.invoke(_targetObject, arguments);
049 }
050
051 Clusterable clusterable = _getClusterable(
052 method, _targetObject.getClass());
053
054 if (clusterable == NullClusterable.NULL_CLUSTERABLE) {
055 return method.invoke(_targetObject, arguments);
056 }
057
058 if (clusterable.onMaster()) {
059 if (ClusterMasterExecutorUtil.isMaster()) {
060 return method.invoke(_targetObject, arguments);
061 }
062
063 return ClusterableInvokerUtil.invokeOnMaster(
064 clusterable.acceptor(), _targetObject, method, arguments);
065 }
066
067 Object result = method.invoke(_targetObject, arguments);
068
069 ClusterableInvokerUtil.invokeOnCluster(
070 clusterable.acceptor(), _targetObject, method, arguments);
071
072 return result;
073 }
074
075 private ClusterableInvocationHandler(T targetObject) {
076 _targetObject = targetObject;
077 }
078
079 private Clusterable _getClusterable(
080 Method method, Class<?> targetClass) {
081
082 MethodKey methodKey = new MethodKey(
083 targetClass, method.getName(), method.getParameterTypes());
084
085 Clusterable clusterable = _clusterables.get(methodKey);
086
087 if (clusterable != null) {
088 return clusterable;
089 }
090
091 clusterable = AnnotationLocator.locate(
092 method, _targetObject.getClass(), Clusterable.class);
093
094 if (clusterable == null) {
095 clusterable = NullClusterable.NULL_CLUSTERABLE;
096 }
097
098 _clusterables.put(methodKey, clusterable);
099
100 return clusterable;
101 }
102
103 private static final Map<MethodKey, Clusterable> _clusterables =
104 new ConcurrentHashMap<>();
105
106 private final T _targetObject;
107
108 }
109
110 }