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