1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sf.ehcache.hibernate.regions;
17
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.Map;
21 import java.util.Properties;
22
23 import net.sf.ehcache.Ehcache;
24 import net.sf.ehcache.Element;
25 import net.sf.ehcache.constructs.nonstop.NonStopCacheException;
26 import net.sf.ehcache.hibernate.nonstop.HibernateNonstopCacheExceptionHandler;
27 import net.sf.ehcache.hibernate.strategy.EhcacheAccessStrategyFactory;
28 import net.sf.ehcache.util.Timestamper;
29
30 import org.hibernate.cache.CacheException;
31 import org.hibernate.cache.Region;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /***
36 * An Ehcache specific data region implementation.
37 * <p>
38 * This class is the ultimate superclass for all Ehcache Hibernate cache regions.
39 *
40 * @author Chris Dennis
41 * @author Greg Luck
42 * @author Emmanuel Bernard
43 * @author Abhishek Sanoujam
44 */
45 public abstract class EhcacheDataRegion implements Region {
46
47 private static final Logger LOG = LoggerFactory.getLogger(EhcacheDataRegion.class);
48
49 private static final String CACHE_LOCK_TIMEOUT_PROPERTY = "net.sf.ehcache.hibernate.cache_lock_timeout";
50 private static final int DEFAULT_CACHE_LOCK_TIMEOUT = 60000;
51
52 /***
53 * Ehcache instance backing this Hibernate data region.
54 */
55 protected final Ehcache cache;
56
57 /***
58 * The {@link EhcacheAccessStrategyFactory} used for creating various access strategies
59 */
60 protected final EhcacheAccessStrategyFactory accessStrategyFactory;
61
62 private final int cacheLockTimeout;
63
64
65 /***
66 * Create a Hibernate data region backed by the given Ehcache instance.
67 */
68 EhcacheDataRegion(EhcacheAccessStrategyFactory accessStrategyFactory, Ehcache cache, Properties properties) {
69 this.accessStrategyFactory = accessStrategyFactory;
70 this.cache = cache;
71 String timeout = properties.getProperty(CACHE_LOCK_TIMEOUT_PROPERTY, Integer.toString(DEFAULT_CACHE_LOCK_TIMEOUT));
72 this.cacheLockTimeout = Timestamper.ONE_MS * Integer.decode(timeout);
73 }
74
75 /***
76 * {@inheritDoc}
77 */
78 public String getName() {
79 return cache.getName();
80 }
81
82 /***
83 * {@inheritDoc}
84 */
85 public void destroy() throws CacheException {
86 try {
87 cache.getCacheManager().removeCache(cache.getName());
88 } catch (IllegalStateException e) {
89
90
91 LOG.debug("This can happen if multiple frameworks both try to shutdown ehcache", e);
92 } catch (net.sf.ehcache.CacheException e) {
93 if (e instanceof NonStopCacheException) {
94 HibernateNonstopCacheExceptionHandler.getInstance().handleNonstopCacheException((NonStopCacheException) e);
95 } else {
96 throw new CacheException(e);
97 }
98 }
99 }
100
101 /***
102 * {@inheritDoc}
103 */
104 public long getSizeInMemory() {
105 try {
106 return cache.calculateInMemorySize();
107 } catch (Throwable t) {
108 if (t instanceof NonStopCacheException) {
109 HibernateNonstopCacheExceptionHandler.getInstance().handleNonstopCacheException((NonStopCacheException) t);
110 }
111 return -1;
112 }
113 }
114
115 /***
116 * {@inheritDoc}
117 */
118 public long getElementCountInMemory() {
119 try {
120 return cache.getMemoryStoreSize();
121 } catch (net.sf.ehcache.CacheException ce) {
122 if (ce instanceof NonStopCacheException) {
123 HibernateNonstopCacheExceptionHandler.getInstance().handleNonstopCacheException((NonStopCacheException) ce);
124 return -1;
125 } else {
126 throw new CacheException(ce);
127 }
128 }
129 }
130
131 /***
132 * {@inheritDoc}
133 */
134 public long getElementCountOnDisk() {
135 try {
136 return cache.getDiskStoreSize();
137 } catch (net.sf.ehcache.CacheException ce) {
138 if (ce instanceof NonStopCacheException) {
139 HibernateNonstopCacheExceptionHandler.getInstance().handleNonstopCacheException((NonStopCacheException) ce);
140 return -1;
141 } else {
142 throw new CacheException(ce);
143 }
144 }
145 }
146
147 /***
148 * {@inheritDoc}
149 */
150 public Map toMap() {
151 try {
152 Map<Object, Object> result = new HashMap<Object, Object>();
153 for (Object key : cache.getKeys()) {
154 Element e = cache.get(key);
155 if (e != null) {
156 result.put(key, e.getObjectValue());
157 }
158 }
159 return result;
160 } catch (Exception e) {
161 if (e instanceof NonStopCacheException) {
162 HibernateNonstopCacheExceptionHandler.getInstance().handleNonstopCacheException((NonStopCacheException) e);
163 return Collections.emptyMap();
164 } else {
165 throw new CacheException(e);
166 }
167 }
168 }
169
170 /***
171 * {@inheritDoc}
172 */
173 public long nextTimestamp() {
174 return Timestamper.next();
175 }
176
177 /***
178 * {@inheritDoc}
179 */
180 public int getTimeout() {
181 return cacheLockTimeout;
182 }
183
184 /***
185 * Return the Ehcache instance backing this Hibernate data region.
186 */
187 public Ehcache getEhcache() {
188 return cache;
189 }
190
191 /***
192 * Returns <code>true</code> if this region contains data for the given key.
193 * <p>
194 * This is a Hibernate 3.5 method.
195 */
196 public boolean contains(Object key) {
197 return cache.isKeyInCache(key);
198 }
199 }