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