001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portal.spring.hibernate;
022:
023: import com.liferay.portal.kernel.cache.CacheKVP;
024: import com.liferay.portal.kernel.cache.CacheRegistry;
025: import com.liferay.portal.kernel.cache.CacheRegistryItem;
026: import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
027: import com.liferay.portal.kernel.cache.PortalCache;
028: import com.liferay.portal.kernel.util.ArrayUtil;
029: import com.liferay.portal.kernel.util.GetterUtil;
030: import com.liferay.portal.kernel.util.StringMaker;
031: import com.liferay.portal.kernel.util.StringPool;
032: import com.liferay.portal.model.BaseModel;
033: import com.liferay.portal.util.PropsUtil;
034: import com.liferay.util.CollectionFactory;
035:
036: import java.io.Serializable;
037:
038: import java.util.ArrayList;
039: import java.util.List;
040: import java.util.Map;
041:
042: import org.hibernate.Session;
043: import org.hibernate.SessionFactory;
044:
045: /**
046: * <a href="FinderCache.java.html"><b><i>View Source</i></b></a>
047: *
048: * @author Brian Wing Shun Chan
049: *
050: */
051: public class FinderCache implements CacheRegistryItem {
052:
053: public static final boolean CACHE_ENABLED = GetterUtil.getBoolean(
054: PropsUtil.get(PropsUtil.VALUE_OBJECT_FINDER_CACHE_ENABLED),
055: true);
056:
057: public static final String CACHE_NAME = FinderCache.class.getName();
058:
059: public static void clearCache() {
060: _instance._clearCache();
061: }
062:
063: public static void clearCache(String className) {
064: _instance._clearCache(className);
065: }
066:
067: public static Object getResult(String className, String methodName,
068: String[] params, Object[] args) {
069:
070: return _instance
071: ._getResult(className, methodName, params, args);
072: }
073:
074: public static Object getResult(String className, String methodName,
075: String[] params, Object[] args,
076: SessionFactory sessionFactory) {
077:
078: return _instance._getResult(className, methodName, params,
079: args, sessionFactory);
080: }
081:
082: public static Object getResult(String sql, String[] classNames,
083: String methodName, String[] params, Object[] args) {
084:
085: return _instance._getResult(sql, classNames, methodName,
086: params, args);
087: }
088:
089: public static Object getResult(String sql, String[] classNames,
090: String methodName, String[] params, Object[] args,
091: SessionFactory sessionFactory) {
092:
093: return _instance._getResult(sql, classNames, methodName,
094: params, args, sessionFactory);
095: }
096:
097: public static void putResult(boolean classNameCacheEnabled,
098: String className, String methodName, String[] params,
099: Object[] args, Object result) {
100:
101: _instance._putResult(classNameCacheEnabled, className,
102: methodName, params, args, result);
103: }
104:
105: public static void putResult(String sql,
106: boolean[] classNamesCacheEnabled, String[] classNames,
107: String methodName, String[] params, Object[] args,
108: Object result) {
109:
110: _instance._putResult(sql, classNamesCacheEnabled, classNames,
111: methodName, params, args, 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(String className, String methodName,
133: String[] params, Object[] args) {
134:
135: return _getResult(className, methodName, params, args, null);
136: }
137:
138: private Object _getResult(String className, String methodName,
139: 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: } finally {
154: HibernateUtil.closeSession(session);
155: }
156: } else {
157: return null;
158: }
159: }
160:
161: private Object _getResult(String sql, String[] classNames,
162: String methodName, String[] params, Object[] args) {
163:
164: return _getResult(sql, classNames, methodName, params, args,
165: null);
166: }
167:
168: private Object _getResult(String sql, String[] classNames,
169: String methodName, String[] params, Object[] args,
170: SessionFactory sessionFactory) {
171:
172: String key = _encodeKey(sql, methodName, params, args);
173:
174: Object primaryKey = MultiVMPoolUtil.get(_cache, key);
175:
176: if (primaryKey != null) {
177: Session session = null;
178:
179: try {
180: session = HibernateUtil.openSession(sessionFactory);
181:
182: return _primaryKeyToResult(session, primaryKey);
183: } finally {
184: HibernateUtil.closeSession(session);
185: }
186: } else {
187: return null;
188: }
189: }
190:
191: private void _putResult(boolean classNameCacheEnabled,
192: String className, String methodName, String[] params,
193: Object[] args, Object result) {
194:
195: if (classNameCacheEnabled && CACHE_ENABLED
196: && CacheRegistry.isActive() && (result != null)) {
197:
198: String key = _encodeKey(className, methodName, params, args);
199:
200: String groupKey = _encodeGroupKey(className);
201:
202: MultiVMPoolUtil.put(_cache, key, _groups, groupKey,
203: _resultToPrimaryKey(result));
204: }
205: }
206:
207: private void _putResult(String sql,
208: boolean[] classNamesCacheEnabled, String[] classNames,
209: String methodName, String[] params, Object[] args,
210: Object result) {
211:
212: if (ArrayUtil.contains(classNamesCacheEnabled, false)) {
213: return;
214: }
215:
216: if (CACHE_ENABLED && CacheRegistry.isActive()
217: && (result != null)) {
218: String key = _encodeKey(sql, methodName, params, args);
219:
220: for (int i = 0; i < classNames.length; i++) {
221: String className = classNames[i];
222:
223: String groupKey = _encodeGroupKey(className);
224:
225: MultiVMPoolUtil.updateGroup(_groups, groupKey, key);
226: }
227:
228: MultiVMPoolUtil.put(_cache, key,
229: _resultToPrimaryKey(result));
230: }
231: }
232:
233: private String _encodeGroupKey(String className) {
234: StringMaker sm = new StringMaker();
235:
236: sm.append(CACHE_NAME);
237: sm.append(StringPool.POUND);
238: sm.append(className);
239:
240: return sm.toString();
241: }
242:
243: private String _encodeKey(String className, String methodName,
244: String[] params, Object[] args) {
245:
246: StringMaker sm = new StringMaker();
247:
248: sm.append(CACHE_NAME);
249: sm.append(StringPool.POUND);
250: sm.append(className);
251: sm.append(StringPool.POUND);
252: sm.append(methodName);
253: sm.append(_PARAMS_SEPARATOR);
254:
255: for (int i = 0; i < params.length; i++) {
256: String param = params[i];
257:
258: sm.append(StringPool.POUND);
259: sm.append(param);
260: }
261:
262: sm.append(_ARGS_SEPARATOR);
263:
264: for (int i = 0; i < args.length; i++) {
265: Object arg = args[i];
266:
267: sm.append(StringPool.POUND);
268: sm.append(String.valueOf(arg));
269: }
270:
271: return sm.toString();
272: }
273:
274: private Object _primaryKeyToResult(Session session,
275: Object primaryKey) {
276:
277: if (primaryKey instanceof CacheKVP) {
278: CacheKVP cacheKVP = (CacheKVP) primaryKey;
279:
280: Class modelClass = cacheKVP.getModelClass();
281: Serializable primaryKeyObj = cacheKVP.getPrimaryKeyObj();
282:
283: return session.load(modelClass, primaryKeyObj);
284: } else if (primaryKey instanceof List) {
285: List cachedList = (List) primaryKey;
286:
287: List list = new ArrayList(cachedList.size());
288:
289: for (int i = 0; i < cachedList.size(); i++) {
290: Object result = _primaryKeyToResult(session, cachedList
291: .get(i));
292:
293: list.add(result);
294: }
295:
296: return list;
297: } else {
298: return primaryKey;
299: }
300: }
301:
302: private Object _resultToPrimaryKey(Object result) {
303: if (result instanceof BaseModel) {
304: BaseModel model = (BaseModel) result;
305:
306: Class modelClass = model.getClass();
307: Serializable primaryKeyObj = model.getPrimaryKeyObj();
308:
309: return new CacheKVP(modelClass, primaryKeyObj);
310: } else if (result instanceof List) {
311: List list = (ArrayList) result;
312:
313: List cachedList = new ArrayList(list.size());
314:
315: for (int i = 0; i < list.size(); i++) {
316: Object primaryKey = _resultToPrimaryKey(list.get(i));
317:
318: cachedList.add(primaryKey);
319: }
320:
321: return cachedList;
322: } else {
323: return result;
324: }
325: }
326:
327: private static final String _ARGS_SEPARATOR = "_ARGS_SEPARATOR_";
328:
329: private static final String _PARAMS_SEPARATOR = "_PARAMS_SEPARATOR_";
330:
331: private static FinderCache _instance = new FinderCache();
332:
333: private PortalCache _cache = MultiVMPoolUtil.getCache(CACHE_NAME);
334:
335: private Map _groups = CollectionFactory.getSyncHashMap();
336:
337: }
|