001
014
015 package com.liferay.portal.kernel.util;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019
020 import java.io.Externalizable;
021 import java.io.IOException;
022 import java.io.ObjectInput;
023 import java.io.ObjectOutput;
024 import java.io.Serializable;
025
026 import java.lang.reflect.Field;
027 import java.lang.reflect.Modifier;
028
029 import java.util.ArrayList;
030 import java.util.List;
031
032
035 public class ThreadLocalDistributor implements Externalizable {
036
037 public void afterPropertiesSet() throws Exception {
038 if (_threadLocalSources == null) {
039 throw new IllegalArgumentException("Thread local sources is null");
040 }
041
042 ClassLoader classLoader = getClassLoader();
043
044 for (KeyValuePair keyValuePair : _threadLocalSources) {
045 String className = keyValuePair.getKey();
046 String fieldName = keyValuePair.getValue();
047
048 Class<?> clazz = classLoader.loadClass(className);
049
050 Field field = ReflectionUtil.getDeclaredField(clazz, fieldName);
051
052 if (!ThreadLocal.class.isAssignableFrom(field.getType())) {
053 if (_log.isWarnEnabled()) {
054 _log.warn(fieldName + " is not of type ThreadLocal");
055 }
056
057 continue;
058 }
059
060 if (!Modifier.isStatic(field.getModifiers())) {
061 if (_log.isWarnEnabled()) {
062 _log.warn(fieldName + " is not a static ThreadLocal");
063 }
064
065 continue;
066 }
067
068 ThreadLocal<Serializable> threadLocal =
069 (ThreadLocal<Serializable>)field.get(null);
070
071 if (threadLocal == null) {
072 if (_log.isWarnEnabled()) {
073 _log.warn(fieldName + " is not initialized");
074 }
075
076 continue;
077 }
078
079 _threadLocals.add(threadLocal);
080 }
081
082 _threadLocalValues = new Serializable[_threadLocals.size()];
083
084 _index = ThreadLocalDistributorRegistry.addThreadLocalDistributor(this);
085 }
086
087 public void capture() {
088 for (int i = 0; i < _threadLocalValues.length; i++) {
089 ThreadLocal<Serializable> threadLocal = _threadLocals.get(i);
090
091 _threadLocalValues[i] = threadLocal.get();
092 }
093 }
094
095 public ClassLoader getClassLoader() {
096 if (_classLoader == null) {
097 Thread currentThread = Thread.currentThread();
098
099 _classLoader = currentThread.getContextClassLoader();
100 }
101
102 return _classLoader;
103 }
104
105 @Override
106 public void readExternal(ObjectInput objectInput)
107 throws ClassNotFoundException, IOException {
108
109 _index = objectInput.readInt();
110 _threadLocalValues = (Serializable[])objectInput.readObject();
111
112 ThreadLocalDistributor threadLocalDistributor =
113 ThreadLocalDistributorRegistry.getThreadLocalDistributor(_index);
114
115 _threadLocals = threadLocalDistributor._threadLocals;
116 }
117
118 public void restore() {
119 for (int i = 0; i < _threadLocalValues.length; i++) {
120 _threadLocals.get(i).set(_threadLocalValues[i]);
121 }
122 }
123
124 public void setClassLoader(ClassLoader classLoader) {
125 _classLoader = classLoader;
126 }
127
128 public void setThreadLocalSources(List<KeyValuePair> threadLocalSources) {
129 _threadLocalSources = threadLocalSources;
130 }
131
132 @Override
133 public void writeExternal(ObjectOutput objectOutput) throws IOException {
134 objectOutput.writeInt(_index);
135 objectOutput.writeObject(_threadLocalValues);
136 }
137
138 private static Log _log = LogFactoryUtil.getLog(
139 ThreadLocalDistributor.class);
140
141 private ClassLoader _classLoader;
142 private int _index;
143 private List<ThreadLocal<Serializable>> _threadLocals =
144 new ArrayList<ThreadLocal<Serializable>>();
145 private List<KeyValuePair> _threadLocalSources;
146 private Serializable[] _threadLocalValues;
147
148 }