001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.components.ocache.impl;
010:
011: import com.completex.objective.components.ocache.*;
012:
013: import java.util.HashMap;
014: import java.util.Map;
015:
016: /**
017: * Default Cache Factory.
018: *
019: * @see LinkedCacheFactoryImpl
020: * @author Gennady Krizhevsky
021: */
022: public class DefaultCacheFactoryImpl implements OdalCacheRegistry {
023:
024: public static final Long LONG_MAX = new Long(Long.MAX_VALUE);
025: public static final Boolean TRUE = Boolean.TRUE;
026: public static final Boolean FALSE = Boolean.FALSE;
027:
028: protected static final OdalCacheConfig DEFAULT_CONFIG = new OdalCacheConfig();
029:
030: public static final String DEFAULT_FLUSH_INTERVAL = "10000:00:00.000";
031:
032: static {
033: DEFAULT_CONFIG.setCacheFlushInterval(DEFAULT_FLUSH_INTERVAL);
034: DEFAULT_CONFIG.setClone(TRUE);
035: DEFAULT_CONFIG.setDisabled(FALSE);
036: DEFAULT_CONFIG.setEntryFlushInterval(DEFAULT_FLUSH_INTERVAL);
037: DEFAULT_CONFIG.setFlatten(TRUE);
038: DEFAULT_CONFIG.setMarkCacheCollectionElements(TRUE);
039: DEFAULT_CONFIG.setMaxSize(new Integer(100));
040: DEFAULT_CONFIG.setTransactionSensitive(TRUE);
041: }
042:
043: private ValueTransformer valueTransformer = ValueTransformer.NULL_VALUE_TRANSFORMER;
044: private boolean transactionSensitive;
045: private OdalCacheConfig globalConfig = DEFAULT_CONFIG
046: .cloneOdalCacheConfig();
047:
048: private HashMap caches = new HashMap();
049:
050: public DefaultCacheFactoryImpl() {
051: DEFAULT_CONFIG.validateAllSet();
052: }
053:
054: /**
055: * Registers either SafeTransactionSensitiveCacheImpl wrapper of the cache if transactionSensitive == true
056: * or SafeBasicCacheImpl otherwise. If the underlying cache passed as a parameter is already of SafeBasicCacheImpl
057: * or BasicCacheImpl type then keyFactory parameter is ignored
058: *
059: * @see OdalCacheRegistry#registerCache(com.completex.objective.components.ocache.OdalCache)
060: */
061: public synchronized void registerCache(OdalCache cache) {
062: registerCache(cache, null, null);
063: }
064:
065: public void registerCache(OdalCache cache,
066: OdalCacheConfig cacheConfig) {
067: registerCache(cache, null, cacheConfig);
068: }
069:
070: /**
071: * Registers either SafeTransactionSensitiveCacheImpl wrapper of the cache if transactionSensitive == true
072: * or SafeBasicCacheImpl otherwise. If the underlying cache passed as a parameter is already of SafeBasicCacheImpl
073: * or BasicCacheImpl type then keyFactory parameter is ignored
074: *
075: * @see OdalCacheRegistry#registerCache(com.completex.objective.components.ocache.OdalCache, com.completex.objective.components.ocache.OdalKeyFactory)
076: */
077: public synchronized void registerCache(OdalCache cache,
078: OdalKeyFactory keyFactory) {
079: registerCache(cache, keyFactory, null);
080: }
081:
082: /**
083: * Registers either SafeTransactionSensitiveCacheImpl wrapper of the cache if transactionSensitive == true
084: * or SafeBasicCacheImpl otherwise. If the underlying cache passed as a parameter is already of SafeBasicCacheImpl
085: * or BasicCacheImpl type then keyFactory parameter is ignored
086: *
087: * @see OdalCacheRegistry#registerCache(com.completex.objective.components.ocache.OdalCache, com.completex.objective.components.ocache.OdalKeyFactory)
088: */
089: public void registerCache(OdalCache cache,
090: OdalKeyFactory keyFactory, OdalCacheConfig cacheConfig) {
091: cacheConfig = OdalCacheConfig.merge(globalConfig, cacheConfig);
092: if (cache != null) {
093: if (cache.getName() == null) {
094: throw new OdalRuntimeCacheException(
095: "Cannot register cache with no name");
096: }
097: if (!cacheConfig.isDisabled()) {
098: if (!caches.containsKey(cache.getName())) {
099: cache = transformCache(
100: cache,
101: keyFactory,
102: cacheConfig.isMarkCacheCollectionElements(),
103: valueTransformer, transactionSensitive);
104: caches.put(cache.getName(), cache);
105: } else {
106: throw new OdalRuntimeCacheException(
107: "Cache with name "
108: + cache.getName()
109: + " already exists. Unregister it 1st");
110: }
111: }
112: }
113: }
114:
115: /**
116: * Transforms cache either to SafeTransactionSensitiveCacheImpl wrapper of the cache if transactionSensitive == true
117: * or SafeBasicCacheImpl otherwise
118: *
119: * @param cache
120: * @param keyFactory
121: * @param markCacheCollectionElements
122: * @param valueTransformer
123: * @param transactionSensitive
124: * @return transformed cache
125: */
126: protected OdalCache transformCache(OdalCache cache,
127: OdalKeyFactory keyFactory,
128: boolean markCacheCollectionElements,
129: ValueTransformer valueTransformer,
130: boolean transactionSensitive) {
131: if (transactionSensitive) {
132: cache = toTransactionSensitiveOdalKeyedCache(cache,
133: keyFactory, markCacheCollectionElements,
134: valueTransformer, true);
135: } else {
136: cache = toOdalKeyedCache(cache, keyFactory,
137: markCacheCollectionElements, valueTransformer, true);
138: }
139: return cache;
140: }
141:
142: protected OdalCache toOdalKeyedCache(OdalCache cache,
143: OdalKeyFactory keyFactory,
144: boolean markCacheCollectionElements,
145: ValueTransformer valueTransformer, boolean safe) {
146: if (!(cache instanceof SafeBasicCacheImpl)) {
147: cache = extractDelegate(cache);
148: if (!(cache instanceof BasicCacheImpl)) {
149: cache = new BasicCacheImpl(cache, keyFactory,
150: valueTransformer, markCacheCollectionElements);
151: }
152: if (safe) {
153: cache = new SafeBasicCacheImpl(((BasicCacheImpl) cache));
154: }
155: }
156: return cache;
157: }
158:
159: protected OdalCache toTransactionSensitiveOdalKeyedCache(
160: OdalCache cache, OdalKeyFactory keyFactory,
161: boolean markCacheCollectionElements,
162: ValueTransformer valueTransformer, boolean safe) {
163: if (!(cache instanceof SafeTransactionSensitiveCacheImpl)) {
164: cache = extractDelegate(cache);
165: keyFactory = extractKeyFactory(cache, keyFactory);
166: if (!(cache instanceof TransactionSensitiveCacheImpl)) {
167: cache = toOdalKeyedCache(cache, keyFactory,
168: markCacheCollectionElements, valueTransformer,
169: false);
170: cache = new TransactionSensitiveCacheImpl(cache,
171: keyFactory, markCacheCollectionElements);
172: }
173: if (safe) {
174: cache = new SafeTransactionSensitiveCacheImpl(
175: ((TransactionSensitiveCacheImpl) cache));
176: }
177: }
178: return cache;
179: }
180:
181: /**
182: * Extracts undelying cache if cache is instance of SafeWrapper
183: *
184: * @param cache
185: * @return undelying cache
186: */
187: protected static OdalCache extractDelegate(OdalCache cache) {
188: if (cache instanceof SafeWrapper) {
189: cache = ((SafeWrapper) cache).getDelegate();
190: }
191: return cache;
192: }
193:
194: /**
195: * Extracts undelying cache key factory if cache is instance of OdalKeyedCache
196: *
197: * @param cache
198: * @param keyFactory
199: * @return undelying cache key factory
200: */
201: protected static OdalKeyFactory extractKeyFactory(OdalCache cache,
202: OdalKeyFactory keyFactory) {
203: if (cache instanceof OdalKeyedCache) {
204: keyFactory = ((OdalKeyedCache) cache).getKeyFactory();
205: }
206: return keyFactory;
207: }
208:
209: /**
210: * @see OdalCacheRegistry#unregisterCache(String)
211: */
212: public synchronized void unregisterCache(String name) {
213: caches.remove(name);
214: }
215:
216: /**
217: * @see OdalCacheFactory#getCache(String)
218: */
219: public synchronized OdalKeyedCache getCache(String name) {
220: OdalKeyedCache cache = (OdalKeyedCache) caches.get(name);
221: return cache == null ? OdalKeyedCache.NULL_ODAL_KEYED_CACHE
222: : cache;
223: }
224:
225: /**
226: * Returns ValueTransformer
227: *
228: * @see ValueTransformer
229: * @return ValueTransformer
230: */
231: public ValueTransformer getValueTransformer() {
232: return valueTransformer;
233: }
234:
235: /**
236: * Sets ValueTransformer
237: *
238: * @see ValueTransformer
239: * @param valueTransformer
240: */
241: public void setValueTransformer(ValueTransformer valueTransformer) {
242: if (valueTransformer != null) {
243: this .valueTransformer = valueTransformer;
244: }
245: }
246:
247: /**
248: * Returns true if the cache returned with #getCache() method is transaction sensitive. For transaction sensitive
249: * cache all the removed items get redundantly removed on commit or rollback.
250: *
251: * @return true if the cache returned is synchronized with transaction
252: */
253: public boolean isTransactionSensitive() {
254: return transactionSensitive;
255: }
256:
257: /**
258: * Set true if the cache returned with #getCache() method is transaction sensitive. For transaction sensitive
259: * cache all the removed items get redundantly removed on commit or rollback.
260: *
261: * @param transactionSensitive
262: */
263: public void setTransactionSensitive(boolean transactionSensitive) {
264: this .transactionSensitive = transactionSensitive;
265: }
266:
267: public OdalCacheConfig getGlobalConfig() {
268: return globalConfig;
269: }
270:
271: public void setGlobalConfig(OdalCacheConfig globalConfig) {
272: this .globalConfig.merge(globalConfig);
273: }
274:
275: protected Map getCaches() {
276: return caches;
277: }
278:
279: }
|