1
22
23 package com.liferay.portal.spring.hibernate;
24
25 import com.liferay.portal.kernel.cache.CacheKVP;
26 import com.liferay.portal.kernel.cache.CacheRegistry;
27 import com.liferay.portal.kernel.cache.CacheRegistryItem;
28 import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
29 import com.liferay.portal.kernel.cache.PortalCache;
30 import com.liferay.portal.kernel.util.ArrayUtil;
31 import com.liferay.portal.kernel.util.GetterUtil;
32 import com.liferay.portal.kernel.util.StringMaker;
33 import com.liferay.portal.kernel.util.StringPool;
34 import com.liferay.portal.model.BaseModel;
35 import com.liferay.portal.util.PropsUtil;
36 import com.liferay.util.CollectionFactory;
37
38 import java.io.Serializable;
39
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.Map;
43
44 import org.hibernate.Session;
45 import org.hibernate.SessionFactory;
46
47
53 public class FinderCache implements CacheRegistryItem {
54
55 public static final boolean CACHE_ENABLED = GetterUtil.getBoolean(
56 PropsUtil.get(PropsUtil.VALUE_OBJECT_FINDER_CACHE_ENABLED), true);
57
58 public static final String CACHE_NAME = FinderCache.class.getName();
59
60 public static void clearCache() {
61 _instance._clearCache();
62 }
63
64 public static void clearCache(String className) {
65 _instance._clearCache(className);
66 }
67
68 public static Object getResult(
69 String className, String methodName, String[] params, Object[] args) {
70
71 return _instance._getResult(className, methodName, params, args);
72 }
73
74 public static Object getResult(
75 String className, String methodName, String[] params, Object[] args,
76 SessionFactory sessionFactory) {
77
78 return _instance._getResult(
79 className, methodName, params, args, sessionFactory);
80 }
81
82 public static Object getResult(
83 String sql, String[] classNames, String methodName, String[] params,
84 Object[] args) {
85
86 return _instance._getResult(sql, classNames, methodName, params, args);
87 }
88
89 public static Object getResult(
90 String sql, String[] classNames, String methodName, String[] params,
91 Object[] args, SessionFactory sessionFactory) {
92
93 return _instance._getResult(
94 sql, classNames, methodName, params, args, sessionFactory);
95 }
96
97 public static void putResult(
98 boolean classNameCacheEnabled, String className, String methodName,
99 String[] params, Object[] args, Object result) {
100
101 _instance._putResult(
102 classNameCacheEnabled, className, methodName, params, args, result);
103 }
104
105 public static void putResult(
106 String sql, boolean[] classNamesCacheEnabled, String[] classNames,
107 String methodName, String[] params, Object[] args, Object result) {
108
109 _instance._putResult(
110 sql, classNamesCacheEnabled, classNames, methodName, params, args,
111 result);
112 }
113
114 public void invalidate() {
115 _clearCache();
116 }
117
118 private FinderCache() {
119 CacheRegistry.register(this);
120 }
121
122 private void _clearCache() {
123 _cache.removeAll();
124 }
125
126 private void _clearCache(String className) {
127 String groupKey = _encodeGroupKey(className);
128
129 MultiVMPoolUtil.clearGroup(_groups, groupKey, _cache);
130 }
131
132 private Object _getResult(
133 String className, String methodName, String[] params, Object[] args) {
134
135 return _getResult(className, methodName, params, args, null);
136 }
137
138 private Object _getResult(
139 String className, String methodName, String[] params, Object[] args,
140 SessionFactory sessionFactory) {
141
142 String key = _encodeKey(className, methodName, params, args);
143
144 Object primaryKey = MultiVMPoolUtil.get(_cache, key);
145
146 if (primaryKey != null) {
147 Session session = null;
148
149 try {
150 session = HibernateUtil.openSession(sessionFactory);
151
152 return _primaryKeyToResult(session, primaryKey);
153 }
154 finally {
155 HibernateUtil.closeSession(session);
156 }
157 }
158 else {
159 return null;
160 }
161 }
162
163 private Object _getResult(
164 String sql, String[] classNames, String methodName, String[] params,
165 Object[] args) {
166
167 return _getResult(sql, classNames, methodName, params, args, null);
168 }
169
170 private Object _getResult(
171 String sql, String[] classNames, String methodName, String[] params,
172 Object[] args, SessionFactory sessionFactory) {
173
174 String key = _encodeKey(sql, methodName, params, args);
175
176 Object primaryKey = MultiVMPoolUtil.get(_cache, key);
177
178 if (primaryKey != null) {
179 Session session = null;
180
181 try {
182 session = HibernateUtil.openSession(sessionFactory);
183
184 return _primaryKeyToResult(session, primaryKey);
185 }
186 finally {
187 HibernateUtil.closeSession(session);
188 }
189 }
190 else {
191 return null;
192 }
193 }
194
195 private void _putResult(
196 boolean classNameCacheEnabled, String className, String methodName,
197 String[] params, Object[] args, Object result) {
198
199 if (classNameCacheEnabled && CACHE_ENABLED &&
200 CacheRegistry.isActive() && (result != null)) {
201
202 String key = _encodeKey(className, methodName, params, args);
203
204 String groupKey = _encodeGroupKey(className);
205
206 MultiVMPoolUtil.put(
207 _cache, key, _groups, groupKey, _resultToPrimaryKey(result));
208 }
209 }
210
211 private void _putResult(
212 String sql, boolean[] classNamesCacheEnabled, String[] classNames,
213 String methodName, String[] params, Object[] args, Object result) {
214
215 if (ArrayUtil.contains(classNamesCacheEnabled, false)) {
216 return;
217 }
218
219 if (CACHE_ENABLED && CacheRegistry.isActive() && (result != null)) {
220 String key = _encodeKey(sql, methodName, params, args);
221
222 for (int i = 0; i < classNames.length; i++) {
223 String className = classNames[i];
224
225 String groupKey = _encodeGroupKey(className);
226
227 MultiVMPoolUtil.updateGroup(_groups, groupKey, key);
228 }
229
230 MultiVMPoolUtil.put(_cache, key, _resultToPrimaryKey(result));
231 }
232 }
233
234 private String _encodeGroupKey(String className) {
235 StringMaker sm = new StringMaker();
236
237 sm.append(CACHE_NAME);
238 sm.append(StringPool.POUND);
239 sm.append(className);
240
241 return sm.toString();
242 }
243
244 private String _encodeKey(
245 String className, String methodName, String[] params, Object[] args) {
246
247 StringMaker sm = new StringMaker();
248
249 sm.append(CACHE_NAME);
250 sm.append(StringPool.POUND);
251 sm.append(className);
252 sm.append(StringPool.POUND);
253 sm.append(methodName);
254 sm.append(_PARAMS_SEPARATOR);
255
256 for (int i = 0; i < params.length; i++) {
257 String param = params[i];
258
259 sm.append(StringPool.POUND);
260 sm.append(param);
261 }
262
263 sm.append(_ARGS_SEPARATOR);
264
265 for (int i = 0; i < args.length; i++) {
266 Object arg = args[i];
267
268 sm.append(StringPool.POUND);
269 sm.append(String.valueOf(arg));
270 }
271
272 return sm.toString();
273 }
274
275 private Object _primaryKeyToResult(
276 Session session, Object primaryKey) {
277
278 if (primaryKey instanceof CacheKVP) {
279 CacheKVP cacheKVP = (CacheKVP)primaryKey;
280
281 Class modelClass = cacheKVP.getModelClass();
282 Serializable primaryKeyObj = cacheKVP.getPrimaryKeyObj();
283
284 return session.load(modelClass, primaryKeyObj);
285 }
286 else if (primaryKey instanceof List) {
287 List cachedList = (List)primaryKey;
288
289 List list = new ArrayList(cachedList.size());
290
291 for (int i = 0; i < cachedList.size(); i++) {
292 Object result = _primaryKeyToResult(session, cachedList.get(i));
293
294 list.add(result);
295 }
296
297 return list;
298 }
299 else {
300 return primaryKey;
301 }
302 }
303
304 private Object _resultToPrimaryKey(Object result) {
305 if (result instanceof BaseModel) {
306 BaseModel model = (BaseModel)result;
307
308 Class modelClass = model.getClass();
309 Serializable primaryKeyObj = model.getPrimaryKeyObj();
310
311 return new CacheKVP(modelClass, primaryKeyObj);
312 }
313 else if (result instanceof List) {
314 List list = (ArrayList)result;
315
316 List cachedList = new ArrayList(list.size());
317
318 for (int i = 0; i < list.size(); i++) {
319 Object primaryKey = _resultToPrimaryKey(list.get(i));
320
321 cachedList.add(primaryKey);
322 }
323
324 return cachedList;
325 }
326 else {
327 return result;
328 }
329 }
330
331 private static final String _ARGS_SEPARATOR = "_ARGS_SEPARATOR_";
332
333 private static final String _PARAMS_SEPARATOR = "_PARAMS_SEPARATOR_";
334
335 private static FinderCache _instance = new FinderCache();
336
337 private PortalCache _cache = MultiVMPoolUtil.getCache(CACHE_NAME);
338
339 private Map _groups = CollectionFactory.getSyncHashMap();
340
341 }