View Javadoc

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              //When Spring and Hibernate are both involved this will happen in normal shutdown operation.
90              //Do not throw an exception, simply log this one.
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 }