1 16 package org.apache.cocoon.components.store.impl; 17 18 import java.io.File ; 19 import java.io.IOException ; 20 import java.io.Serializable ; 21 import java.util.Arrays ; 22 import java.util.Enumeration ; 23 import java.util.Properties ; 24 25 import org.apache.avalon.framework.activity.Disposable; 26 import org.apache.avalon.framework.activity.Initializable; 27 import org.apache.avalon.framework.context.Context; 28 import org.apache.avalon.framework.context.ContextException; 29 import org.apache.avalon.framework.context.Contextualizable; 30 import org.apache.avalon.framework.logger.AbstractLogEnabled; 31 import org.apache.avalon.framework.parameters.ParameterException; 32 import org.apache.avalon.framework.parameters.Parameterizable; 33 import org.apache.avalon.framework.parameters.Parameters; 34 import org.apache.avalon.framework.service.ServiceException; 35 import org.apache.avalon.framework.service.ServiceManager; 36 import org.apache.avalon.framework.service.Serviceable; 37 import org.apache.avalon.framework.thread.ThreadSafe; 38 import org.apache.cocoon.Constants; 39 import org.apache.cocoon.util.IOUtils; 40 import org.apache.commons.collections.iterators.IteratorEnumeration; 41 import org.apache.excalibur.store.Store; 42 import org.apache.excalibur.store.StoreJanitor; 43 import org.apache.jcs.access.GroupCacheAccess; 44 import org.apache.jcs.access.exception.CacheException; 45 import org.apache.jcs.engine.control.CompositeCache; 46 import org.apache.jcs.engine.control.CompositeCacheManager; 47 import org.apache.jcs.engine.memory.MemoryCache; 48 49 50 56 public class JCSDefaultStore 57 extends AbstractLogEnabled 58 implements Store, 59 Contextualizable, 60 Parameterizable, 61 Initializable, 62 Disposable, 63 ThreadSafe, 64 Serviceable { 65 66 67 protected Properties properties; 68 69 70 protected String region; 71 72 73 private CompositeCacheManager cacheManager; 74 75 76 private JCSCacheAccess jcs; 77 78 79 private static final String DEFAULT_PROPERTIES = "org/apache/cocoon/components/store/default.ccf"; 80 81 82 private Context context; 83 84 85 private ServiceManager manager; 86 87 88 private StoreJanitor janitor; 89 90 93 public void contextualize(Context aContext) throws ContextException { 94 this.context = aContext; 95 } 96 97 100 public void service(ServiceManager aManager) throws ServiceException { 101 this.manager = aManager; 102 this.janitor = (StoreJanitor)this.manager.lookup(StoreJanitor.ROLE); 103 } 104 105 108 public void parameterize(Parameters parameters) 109 throws ParameterException { 110 this.region = parameters.getParameter("region-name","main"); 112 113 Properties defaults = new Properties (); 114 try { 115 String defaultsFile = this.getDefaultPropertiesFile(); 116 if (defaultsFile != null) { 117 defaults.load(Thread.currentThread().getContextClassLoader(). 118 getResourceAsStream(defaultsFile)); 119 } 120 } catch (IOException e) { 121 throw new ParameterException("Failure loading cache defaults",e); 122 } 123 124 this.properties = new Properties (defaults); 125 String [] names = parameters.getNames(); 126 for (int i = 0; i < names.length; i++) { 127 if (names[i].startsWith("jcs.")) { 128 this.properties.put(names[i], parameters.getParameter(names[i])); 129 } 130 } 131 132 int maxobjects = parameters.getParameterAsInteger("maxobjects", -1); 133 if (maxobjects != -1) { 134 String key = "jcs.region." + region + ".cacheattributes.MaxObjects"; 135 this.properties.setProperty(key, String.valueOf(maxobjects)); 136 } 137 138 try { 140 final File workDir = (File ) context.get(Constants.CONTEXT_WORK_DIR); 141 if (parameters.getParameterAsBoolean("use-cache-directory", false)) { 142 final File cacheDir = (File ) context.get(Constants.CONTEXT_CACHE_DIR); 143 if (getLogger().isDebugEnabled()) { 144 getLogger().debug("Using cache directory: " + cacheDir); 145 } 146 setDirectory(cacheDir); 147 } else if (parameters.getParameterAsBoolean("use-work-directory", false)) { 148 if (getLogger().isDebugEnabled()) { 149 getLogger().debug("Using work directory: " + workDir); 150 } 151 setDirectory(workDir); 152 } else if (parameters.getParameter("directory", null) != null) { 153 String dir = parameters.getParameter("directory"); 154 dir = IOUtils.getContextFilePath(workDir.getPath(), dir); 155 if (getLogger().isDebugEnabled()) { 156 getLogger().debug("Using directory: " + dir); 157 } 158 setDirectory(new File (dir)); 159 } else { 160 if (getLogger().isDebugEnabled()) { 161 getLogger().debug("Using default directory: " + workDir); 162 } 163 setDirectory(workDir); 164 } 165 } catch (ContextException ce) { 166 throw new ParameterException("Unable to get directory information from context.", ce); 167 } catch (IOException e) { 168 throw new ParameterException("Unable to set directory", e); 169 } 170 171 } 172 173 176 public void initialize() throws Exception { 177 this.cacheManager = CompositeCacheManager.getUnconfiguredInstance(); 178 this.cacheManager.configure(this.properties); 179 this.jcs = new JCSCacheAccess(cacheManager.getCache(region)); 180 this.janitor.register(this); 181 } 182 183 186 public void dispose() { 187 if( this.janitor != null ) { 188 this.janitor.unregister( this ); 189 } 190 if ( this.jcs != null ) { 191 this.jcs.dispose(); 192 this.jcs = null; 193 } 194 if ( this.cacheManager != null ) { 195 this.cacheManager.release(); 196 this.cacheManager = null; 197 } 198 this.properties = null; 199 if ( this.manager != null ) { 200 this.manager.release( this.janitor ); 201 this.janitor = null; 202 this.manager = null; 203 } 204 } 205 206 protected String getDefaultPropertiesFile() { 207 return DEFAULT_PROPERTIES; 208 } 209 210 213 private void setDirectory(final File directory) 214 throws IOException { 215 216 217 if (!directory.exists()) { 218 219 if (!directory.mkdirs()) { 220 throw new IOException ( 221 "Error creating store directory '" + directory.getAbsolutePath() + "'. "); 222 } 223 } 224 225 226 if (!directory.isDirectory()) { 227 throw new IOException ("'" + directory.getAbsolutePath() + "' is not a directory"); 228 } 229 230 231 if (!(directory.canRead() && directory.canWrite())) { 232 throw new IOException ( 233 "Directory '" + directory.getAbsolutePath() + "' is not readable/writable" 234 ); 235 } 236 237 this.properties.setProperty("jcs.auxiliary.DC.attributes.DiskPath", 238 directory.getAbsolutePath()); 239 } 240 241 243 246 public Object get(Object key) { 247 Object value = this.jcs.get(key); 248 if (getLogger().isDebugEnabled()) { 249 if (value != null) { 250 getLogger().debug("Found key: " + key); 251 } else { 252 getLogger().debug("NOT Found key: " + key); 253 } 254 } 255 256 return value; 257 } 258 259 262 public void store(Object key, Object value) 263 throws IOException { 264 265 if (getLogger().isDebugEnabled()) { 266 getLogger().debug("Store object " + value + " with key "+ key); 267 } 268 269 try { 270 this.jcs.put(key, value); 271 } catch (CacheException ce) { 272 getLogger().error("Failure storing object ", ce); 273 } 274 } 275 276 279 public void free() { 280 MemoryCache memoryCache = this.cacheManager.getCache(region).getMemoryCache(); 282 Object [] keys = memoryCache.getKeyArray(); 283 if ( keys != null && keys.length > 0 ) { 284 final Object key = keys[0]; 285 try { 286 memoryCache.remove((Serializable )key); 287 } catch (Exception ignore) { 288 } 289 } 290 } 291 292 295 public void clear() { 296 if (getLogger().isDebugEnabled()) { 297 getLogger().debug("Clearing the store"); 298 } 299 300 try { 301 this.jcs.remove(); 302 } catch (CacheException ce) { 303 getLogger().error("Failure clearing store", ce); 304 } 305 } 306 307 310 public void remove(Object key) { 311 if (getLogger().isDebugEnabled()) { 312 getLogger().debug("Removing item " + key); 313 } 314 315 try { 316 this.jcs.remove(key); 317 } catch (CacheException ce) { 318 getLogger().error("Failure removing object", ce); 319 } 320 } 321 322 325 public boolean containsKey(Object key) { 326 return this.jcs.get(key) != null; 327 } 328 329 330 333 public Enumeration keys() { 334 final MemoryCache memoryCache = this.cacheManager.getCache(region).getMemoryCache(); 336 final Object [] keys = memoryCache.getKeyArray(); 337 return new IteratorEnumeration(Arrays.asList(keys).iterator()); 338 } 340 341 344 public int size() { 345 MemoryCache memoryCache = this.cacheManager.getCache(region).getMemoryCache(); 347 return memoryCache.getSize(); 348 } 350 351 352 private static class JCSCacheAccess extends GroupCacheAccess { 353 private JCSCacheAccess(CompositeCache cacheControl) { 354 super(cacheControl); 355 } 356 357 360 361 public void dispose() { 362 super.dispose(); 363 } 364 } 365 366 } 367 | Popular Tags |