View Javadoc

1   /*
2    * Copyright 2007 Hippo
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" 
12   * BASIS, 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 nl.hippo.client.caching;
17  
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.util.Arrays;
21  import java.util.Iterator;
22  import java.util.Map;
23  import java.util.Properties;
24  
25  import nl.hippo.client.api.caching.Cache;
26  
27  import org.apache.jcs.access.GroupCacheAccess;
28  import org.apache.jcs.access.exception.CacheException;
29  import org.apache.jcs.engine.control.CompositeCacheManager;
30  import org.apache.jcs.engine.memory.MemoryCache;
31  
32  public class JCSDefaultCache implements Cache {
33  
34      /** JCS Cache manager */
35      private CompositeCacheManager cacheManager;
36  
37      /** The Java Cache System object */
38      private GroupCacheAccess jcsCache;
39  
40      /** The JCS configuration properties */
41      protected Properties properties;
42  
43      /** the default Cache region */
44      private String cacheRegion;
45  
46      private static final String DEFAULT_CONFIG = "resources/cache.ccf";
47  
48      private static final String PROPS_JCS_REGION_PREFIX = "nl.hippo.client.caching.JCSDefaultCache.jcs.region";
49  
50      public JCSDefaultCache(String cacheRegion) {
51          this(cacheRegion, getDefaultProps(cacheRegion), null);
52      }
53  
54      public JCSDefaultCache(String cacheRegion, Properties props) {
55          this(cacheRegion, getDefaultProps(cacheRegion), getTransformedProps(props, cacheRegion));
56      }
57  
58      public JCSDefaultCache(String cacheRegion, Properties props, Properties propsIn) {
59          if (propsIn != null) {
60              props.putAll(propsIn);
61          }
62          this.cacheRegion = cacheRegion;
63          this.cacheManager = new CompositeCacheManager();
64          this.cacheManager.configure(props);
65          this.jcsCache = new GroupCacheAccess(cacheManager.getCache(cacheRegion));
66  
67          // just to make sure the any diskcache is fully emptied
68          // JCS doesn't seem to clear de diskcache if keys are found on startup
69          // this will force clear the cache
70          clear();
71      }
72  
73      public void dispose() {
74          if (this.jcsCache != null) {
75              // since we do not use persistent cache ever, because of weakreferences in 
76              // event registry, clear the caches on dispose
77              try {
78                  this.jcsCache.clear();
79              } catch (CacheException e) {
80                  e.printStackTrace();
81              }
82              this.jcsCache.dispose();
83              this.jcsCache = null;
84          }
85          if (this.cacheManager != null) {
86              this.cacheManager.release();
87              this.cacheManager = null;
88          }
89          this.properties = null;
90      }
91  
92      public Object get(Object key) {
93          Object value = this.jcsCache.get(key);
94          return value;
95      }
96  
97      /**
98       * Implementation of nl.hippo.cachemanager.api.Cache
99       */
100     public void store(Object key, Object value) throws IOException {
101         try {
102             this.jcsCache.put(key, value);
103         } catch (CacheException e) {
104             e.printStackTrace();
105         }
106     }
107 
108     /**
109      * Implementation of nl.hippo.cachemanager.api.Cache
110      */
111     public void remove(Object key) {
112         try {
113             this.jcsCache.remove(key);
114         } catch (CacheException e) {
115             e.printStackTrace();
116         }
117     }
118 
119     /**
120      * Implementation of nl.hippo.cachemanager.api.Cache
121      */
122     public void clear() {
123         try {
124             this.jcsCache.clear();
125         } catch (CacheException e) {
126             e.printStackTrace();
127         }
128     }
129 
130     /**
131      * Implementation of nl.hippo.cachemanager.api.Cache
132      */
133     public boolean containsKey(Object key) {
134         return this.jcsCache.get(key) != null;
135     }
136 
137     /**
138      * Implementation of nl.hippo.cachemanager.api.Cache
139      */
140     public Iterator memoryKeys() {
141         MemoryCache memoryCache = this.cacheManager.getCache(cacheRegion).getMemoryCache();
142         Object[] keys = memoryCache.getKeyArray();
143         return Arrays.asList(keys).iterator();
144     }
145 
146     /**
147      * Implementation of nl.hippo.cachemanager.api.Cache
148      */
149     public int memorySize() {
150         MemoryCache memoryCache = this.cacheManager.getCache(cacheRegion).getMemoryCache();
151         return memoryCache.getSize();
152     }
153 
154     /**
155      * Implementation of nl.hippo.cachemanager.api.Cache
156      */
157     public String getStatisticsOverview() {
158         return jcsCache.getStats();
159     }
160 
161     private static Properties getDefaultProps(String cacheRegion) {
162         InputStream in = JCSDefaultCache.class.getResourceAsStream(DEFAULT_CONFIG);
163         Properties defaults = new Properties();
164 
165         if (in != null) {
166             try {
167                 defaults.load(in);
168             } catch (IOException e1) {
169                 e1.printStackTrace();
170             }
171         }
172 
173         Properties prop = new Properties();
174         prop.putAll(defaults);
175 
176         prop.setProperty("jcs.auxiliary.JCSDEFAULT.attributes.DiskPath", System.getProperty("java.io.tmpdir"));
177         prop.setProperty("jcs.region." + cacheRegion, "JCSDEFAULT");
178         prop.setProperty("jcs.region." + cacheRegion + ".cacheattributes",
179                 "org.apache.jcs.engine.CompositeCacheAttributes");
180         prop.setProperty("jcs.region." + cacheRegion + ".cacheattributes.MaxObjects", "500");
181         prop.setProperty("jcs.region." + cacheRegion + ".cacheattributes.MemoryCacheName",
182                 "org.apache.jcs.engine.memory.lru.LRUMemoryCache");
183         prop.setProperty("jcs.region." + cacheRegion + ".cacheattributes.UseMemoryShrinker", "true");
184         prop.setProperty("jcs.region." + cacheRegion + ".cacheattributes.MaxMemoryIdleTimeSeconds", "86400");
185         prop.setProperty("jcs.region." + cacheRegion + ".cacheattributes.ShrinkerIntervalSeconds", "300");
186         return prop;
187     }
188 
189     private static Properties getTransformedProps(Properties props, String cacheRegion) {
190         Properties transforedProps = new Properties();
191         Iterator it = props.entrySet().iterator();
192         while (it.hasNext()) {
193             Map.Entry entry = (Map.Entry) it.next();
194             String prop = (String) entry.getKey();
195             if (prop.startsWith(PROPS_JCS_REGION_PREFIX)) {
196                 transforedProps.put("jcs.region." + cacheRegion + prop.substring(PROPS_JCS_REGION_PREFIX.length()),
197                         entry.getValue());
198             } else {
199                 transforedProps.put(prop, props.get(prop));
200             }
201         }
202         return transforedProps;
203     }
204 
205 }