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