1
22
23 package com.liferay.portal.dao.orm.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.MultiVMPool;
29 import com.liferay.portal.kernel.cache.PortalCache;
30 import com.liferay.portal.kernel.dao.orm.FinderCache;
31 import com.liferay.portal.kernel.dao.orm.Session;
32 import com.liferay.portal.kernel.dao.orm.SessionFactory;
33 import com.liferay.portal.kernel.util.ArrayUtil;
34 import com.liferay.portal.kernel.util.GetterUtil;
35 import com.liferay.portal.kernel.util.StringPool;
36 import com.liferay.portal.model.BaseModel;
37 import com.liferay.portal.util.PropsKeys;
38 import com.liferay.portal.util.PropsUtil;
39
40 import java.io.Serializable;
41
42 import java.util.ArrayList;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Set;
46 import java.util.concurrent.ConcurrentHashMap;
47
48
54 public class FinderCacheImpl implements CacheRegistryItem, FinderCache {
55
56 public static final boolean CACHE_ENABLED = GetterUtil.getBoolean(
57 PropsUtil.get(PropsKeys.VALUE_OBJECT_FINDER_CACHE_ENABLED), true);
58
59 public static final String CACHE_NAME = FinderCache.class.getName();
60
61 public void afterPropertiesSet() {
62 CacheRegistry.register(this);
63
64 _cache = _multiVMPool.getCache(CACHE_NAME);
65 }
66
67 public void clearCache() {
68 _cache.removeAll();
69 }
70
71 public void clearCache(String className) {
72 String groupKey = _encodeGroupKey(className);
73
74 _multiVMPool.clearGroup(_groups, groupKey, _cache);
75 }
76
77 public String getRegistryName() {
78 return CACHE_NAME;
79 }
80
81 public Object getResult(
82 String className, String methodName, String[] params, Object[] args,
83 SessionFactory sessionFactory) {
84
85 String key = _encodeKey(className, methodName, params, args);
86
87 Object primaryKey = _multiVMPool.get(_cache, key);
88
89 if (primaryKey != null) {
90 Session session = null;
91
92 try {
93 session = sessionFactory.openSession();
94
95 return _primaryKeyToResult(session, primaryKey);
96 }
97 finally {
98 sessionFactory.closeSession(session);
99 }
100 }
101 else {
102 return null;
103 }
104 }
105
106 public Object getResult(
107 String sql, String[] classNames, String methodName, String[] params,
108 Object[] args, SessionFactory sessionFactory) {
109
110 String key = _encodeKey(sql, methodName, params, args);
111
112 Object primaryKey = _multiVMPool.get(_cache, key);
113
114 if (primaryKey != null) {
115 Session session = null;
116
117 try {
118 session = sessionFactory.openSession();
119
120 return _primaryKeyToResult(session, primaryKey);
121 }
122 finally {
123 sessionFactory.closeSession(session);
124 }
125 }
126 else {
127 return null;
128 }
129 }
130
131 public void invalidate() {
132 clearCache();
133 }
134
135 public void putResult(
136 boolean classNameCacheEnabled, String className, String methodName,
137 String[] params, Object[] args, Object result) {
138
139 if (classNameCacheEnabled && CACHE_ENABLED &&
140 CacheRegistry.isActive() && (result != null)) {
141
142 String key = _encodeKey(className, methodName, params, args);
143
144 String groupKey = _encodeGroupKey(className);
145
146 _multiVMPool.put(
147 _cache, key, _groups, groupKey, _resultToPrimaryKey(result));
148 }
149 }
150
151 public void putResult(
152 String sql, boolean[] classNamesCacheEnabled, String[] classNames,
153 String methodName, String[] params, Object[] args, Object result) {
154
155 if (ArrayUtil.contains(classNamesCacheEnabled, false)) {
156 return;
157 }
158
159 if (CACHE_ENABLED && CacheRegistry.isActive() && (result != null)) {
160 String key = _encodeKey(sql, methodName, params, args);
161
162 for (String className : classNames) {
163 String groupKey = _encodeGroupKey(className);
164
165 _multiVMPool.updateGroup(_groups, groupKey, key);
166 }
167
168 _multiVMPool.put(_cache, key, _resultToPrimaryKey(result));
169 }
170 }
171
172 public void setMultiVMPool(MultiVMPool multiVMPool) {
173 _multiVMPool = multiVMPool;
174 }
175
176 private String _encodeGroupKey(String className) {
177 StringBuilder sb = new StringBuilder();
178
179 sb.append(CACHE_NAME);
180 sb.append(StringPool.POUND);
181 sb.append(className);
182
183 return sb.toString();
184 }
185
186 private String _encodeKey(
187 String className, String methodName, String[] params, Object[] args) {
188
189 StringBuilder sb = new StringBuilder();
190
191 sb.append(CACHE_NAME);
192 sb.append(StringPool.POUND);
193 sb.append(className);
194 sb.append(StringPool.POUND);
195 sb.append(methodName);
196 sb.append(_PARAMS_SEPARATOR);
197
198 for (String param : params) {
199 sb.append(StringPool.POUND);
200 sb.append(param);
201 }
202
203 sb.append(_ARGS_SEPARATOR);
204
205 for (Object arg : args) {
206 sb.append(StringPool.POUND);
207 sb.append(String.valueOf(arg));
208 }
209
210 return sb.toString();
211 }
212
213 private Object _primaryKeyToResult(
214 Session session, Object primaryKey) {
215
216 if (primaryKey instanceof CacheKVP) {
217 CacheKVP cacheKVP = (CacheKVP)primaryKey;
218
219 Class<?> modelClass = cacheKVP.getModelClass();
220 Serializable primaryKeyObj = cacheKVP.getPrimaryKeyObj();
221
222 return session.load(modelClass, primaryKeyObj);
223 }
224 else if (primaryKey instanceof List) {
225 List<Object> cachedList = (List<Object>)primaryKey;
226
227 List<Object> list = new ArrayList<Object>(cachedList.size());
228
229 for (Object curPrimaryKey : cachedList) {
230 Object result = _primaryKeyToResult(session, curPrimaryKey);
231
232 list.add(result);
233 }
234
235 return list;
236 }
237 else {
238 return primaryKey;
239 }
240 }
241
242 private Object _resultToPrimaryKey(Object result) {
243 if (result instanceof BaseModel) {
244 BaseModel model = (BaseModel)result;
245
246 Class<?> modelClass = model.getClass();
247 Serializable primaryKeyObj = model.getPrimaryKeyObj();
248
249 return new CacheKVP(modelClass, primaryKeyObj);
250 }
251 else if (result instanceof List) {
252 List<Object> list = (List<Object>)result;
253
254 List<Object> cachedList = new ArrayList<Object>(list.size());
255
256 for (Object curResult : list) {
257 Object primaryKey = _resultToPrimaryKey(curResult);
258
259 cachedList.add(primaryKey);
260 }
261
262 return cachedList;
263 }
264 else {
265 return result;
266 }
267 }
268
269 private static final String _ARGS_SEPARATOR = "_ARGS_SEPARATOR_";
270
271 private static final String _PARAMS_SEPARATOR = "_PARAMS_SEPARATOR_";
272
273 private MultiVMPool _multiVMPool;
274 private PortalCache _cache;
275 private Map<String, Set<String>> _groups =
276 new ConcurrentHashMap<String, Set<String>>();
277
278 }