001
014
015 package com.liferay.portal.messaging.async;
016
017 import com.liferay.portal.kernel.bean.IdentifiableBean;
018 import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
019 import com.liferay.portal.kernel.bean.PortletBeanLocatorUtil;
020 import com.liferay.portal.kernel.util.ClassLoaderPool;
021 import com.liferay.portal.kernel.util.MethodHandler;
022 import com.liferay.portal.kernel.util.MethodKey;
023 import com.liferay.portal.kernel.util.Validator;
024 import com.liferay.portal.util.ClassLoaderUtil;
025 import com.liferay.portal.util.PortalUtil;
026
027 import java.io.Externalizable;
028 import java.io.IOException;
029 import java.io.ObjectInput;
030 import java.io.ObjectOutput;
031
032 import org.aopalliance.intercept.MethodInvocation;
033
034
037 public class AsyncRunnable implements Externalizable, Runnable {
038
039 public AsyncRunnable() {
040 }
041
042 public AsyncRunnable(MethodInvocation methodInvocation) {
043 _methodInvocation = methodInvocation;
044 }
045
046 @Override
047 public void readExternal(ObjectInput objectInput)
048 throws ClassNotFoundException, IOException {
049
050 _methodHandler = (MethodHandler)objectInput.readObject();
051 }
052
053 @Override
054 public void run() {
055 try {
056 if (_methodInvocation != null) {
057 _methodInvocation.proceed();
058 }
059 else {
060 AsyncInvokeThreadLocal.setEnabled(true);
061
062 try {
063 _methodHandler.invoke(null);
064 }
065 finally {
066 AsyncInvokeThreadLocal.setEnabled(false);
067 }
068 }
069 }
070 catch (Throwable t) {
071 throw new RuntimeException(t);
072 }
073 }
074
075 @Override
076 public void writeExternal(ObjectOutput objectOutput) throws IOException {
077 MethodHandler methodHandler = _methodHandler;
078
079 if (methodHandler == null) {
080 Thread currentThread = Thread.currentThread();
081
082 ClassLoader contextClassLoader =
083 currentThread.getContextClassLoader();
084
085 String servletContextName = ClassLoaderPool.getContextName(
086 contextClassLoader);
087
088 methodHandler = new MethodHandler(
089 _methodInvocation.getMethod(),
090 _methodInvocation.getArguments());
091
092 Object thisObject = _methodInvocation.getThis();
093
094 IdentifiableBean identifiableBean = (IdentifiableBean)thisObject;
095
096 Class<?> identifiableBeanClass = identifiableBean.getClass();
097
098 ClassLoader identifiableBeanClassLoader =
099 identifiableBeanClass.getClassLoader();
100
101 String identifiableBeanServletContextName =
102 ClassLoaderPool.getContextName(identifiableBeanClassLoader);
103
104 String beanIdentifier = identifiableBean.getBeanIdentifier();
105
106 methodHandler = new MethodHandler(
107 _invokeMethodKey, methodHandler, servletContextName,
108 identifiableBeanServletContextName, beanIdentifier);
109 }
110
111 objectOutput.writeObject(methodHandler);
112 }
113
114 @SuppressWarnings("unused")
115 private static Object _invoke(
116 MethodHandler methodHandler, String servletContextName,
117 String identifiableBeanServletContextName, String beanIdentifier)
118 throws Exception {
119
120 if (Validator.isNull(servletContextName)) {
121 if (Validator.isNull(beanIdentifier)) {
122 return methodHandler.invoke(true);
123 }
124
125 Object bean = PortalBeanLocatorUtil.locate(beanIdentifier);
126
127 return methodHandler.invoke(bean);
128 }
129
130 ClassLoader contextClassLoader =
131 ClassLoaderUtil.getContextClassLoader();
132
133 try {
134 ClassLoader classLoader = ClassLoaderPool.getClassLoader(
135 servletContextName);
136
137 ClassLoaderUtil.setContextClassLoader(classLoader);
138
139 if (Validator.isNull(beanIdentifier)) {
140 return methodHandler.invoke(true);
141 }
142
143 Object bean = null;
144
145 if (identifiableBeanServletContextName.equals(
146 PortalUtil.getServletContextName())) {
147
148 bean = PortalBeanLocatorUtil.locate(beanIdentifier);
149 }
150 else {
151 bean = PortletBeanLocatorUtil.locate(
152 servletContextName, beanIdentifier);
153 }
154
155 return methodHandler.invoke(bean);
156 }
157 finally {
158 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
159 }
160 }
161
162 private static MethodKey _invokeMethodKey = new MethodKey(
163 AsyncRunnable.class, "_invoke", MethodHandler.class, String.class,
164 String.class, String.class);
165
166 private MethodHandler _methodHandler;
167 private MethodInvocation _methodInvocation;
168
169 }