cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: rev 55151 - in cocoon/trunk: lib lib/core src/blocks/scratchpad/conf src/blocks/scratchpad/java/org/apache/cocoon/components/store src/blocks/scratchpad/lib src/blocks/xsp/java/org/apache/cocoon/acting src/java/org/apache/cocoon src/java/org/apache/cocoon/components/store/impl src/webapp/WEB-INF
Date Wed, 20 Oct 2004 13:29:37 GMT
Author: cziegeler
Date: Wed Oct 20 06:29:36 2004
New Revision: 55151

Added:
   cocoon/trunk/lib/core/ehcache-1.0.jar   (contents, props changed)
   cocoon/trunk/src/java/org/apache/cocoon/components/store/impl/EHDefaultStore.java
   cocoon/trunk/src/java/org/apache/cocoon/components/store/impl/ehcache.xml
Removed:
   cocoon/trunk/src/blocks/scratchpad/conf/ehstore.xconf
   cocoon/trunk/src/blocks/scratchpad/java/org/apache/cocoon/components/store/EHStore.java
   cocoon/trunk/src/blocks/scratchpad/java/org/apache/cocoon/components/store/ehcache-defaults.xml
   cocoon/trunk/src/blocks/scratchpad/lib/ehcache-0.9.jar
Modified:
   cocoon/trunk/lib/jars.xml
   cocoon/trunk/src/blocks/xsp/java/org/apache/cocoon/acting/ServerPagesAction.java
   cocoon/trunk/src/java/org/apache/cocoon/cocoon.roles
   cocoon/trunk/src/webapp/WEB-INF/cocoon.xconf
Log:
ehcache is now in the core

Added: cocoon/trunk/lib/core/ehcache-1.0.jar
==============================================================================
Binary file. No diff available.

Modified: cocoon/trunk/lib/jars.xml
==============================================================================
--- cocoon/trunk/lib/jars.xml	(original)
+++ cocoon/trunk/lib/jars.xml	Wed Oct 20 06:29:36 2004
@@ -558,7 +558,7 @@
     <title>EHCache</title>
     <description>Easy Hibernate Cache</description>
     <used-by>EHCache Store</used-by>
-    <lib>scratchpad/lib/ehcache-0.9.jar</lib>
+    <lib>core/ehcache-1.0.jar</lib>
     <homepage>http://ehcache.sourceforge.net/</homepage>
   </file>
 

Modified: cocoon/trunk/src/blocks/xsp/java/org/apache/cocoon/acting/ServerPagesAction.java
==============================================================================
--- cocoon/trunk/src/blocks/xsp/java/org/apache/cocoon/acting/ServerPagesAction.java	(original)
+++ cocoon/trunk/src/blocks/xsp/java/org/apache/cocoon/acting/ServerPagesAction.java	Wed Oct
20 06:29:36 2004
@@ -40,12 +40,6 @@
 import org.apache.cocoon.xml.AbstractXMLConsumer;
 
 /**
- * @author CZiegeler
- *
- * To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
- */
-/**
  * Allows actions to be written in XSP. This allows to use XSP to produce
  * XML fragments that are later reused in generators.<br/>
  *
@@ -79,7 +73,7 @@
  * </pre>
  *
  * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
- * @version CVS $Id: ServerPagesAction.java,v 1.2 2004/05/24 12:37:52 cziegeler Exp $
+ * @version CVS $Id$
  */
 public class ServerPagesAction
         extends AbstractAction

Modified: cocoon/trunk/src/java/org/apache/cocoon/cocoon.roles
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/cocoon.roles	(original)
+++ cocoon/trunk/src/java/org/apache/cocoon/cocoon.roles	Wed Oct 20 06:29:36 2004
@@ -77,7 +77,7 @@
   <!-- Stores: -->
   <role name="org.apache.excalibur.store.Store"
        shorthand="store"
-       default-class="org.apache.cocoon.components.store.impl.JCSDefaultStore"/>
+       default-class="org.apache.cocoon.components.store.impl.EHDefaultStore"/>
 
   <role name="org.apache.excalibur.store.Store/TransientStore"
         shorthand="transient-store"

Added: cocoon/trunk/src/java/org/apache/cocoon/components/store/impl/EHDefaultStore.java
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/store/impl/EHDefaultStore.java	Wed
Oct 20 06:29:36 2004
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2004,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.store.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.util.IOUtils;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.store.StoreJanitor;
+
+/**
+ * Store implementation based on EHCache.
+ * (http://ehcache.sourceforge.net/)
+ */
+public class EHDefaultStore extends AbstractLogEnabled 
+implements Store, Contextualizable, Serviceable, Parameterizable, Initializable, Disposable,
ThreadSafe {
+
+    // ---------------------------------------------------- Constants
+
+    private static final String CONFIG_FILE = "org/apache/cocoon/components/store/impl/ehcache.xml";
+
+    private static int instanceCount = 0;
+
+    // ---------------------------------------------------- Instance variables
+
+    private Cache cache;
+    private CacheManager cacheManager;
+
+    private final String cacheName;
+
+    // configuration options
+    private int maxObjects;
+    private boolean overflowToDisk;
+
+    /** The service manager */
+    private ServiceManager manager;
+    
+    /** The store janitor */
+    private StoreJanitor storeJanitor;
+
+    private File workDir;
+    private File cacheDir;
+
+    // ---------------------------------------------------- Lifecycle
+
+    public EHDefaultStore() {
+        instanceCount++;
+        this.cacheName = "cocoon-ehcache-" + instanceCount;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.workDir = (File)context.get(Constants.CONTEXT_WORK_DIR);
+        this.cacheDir = (File)context.get(Constants.CONTEXT_CACHE_DIR);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager aManager) throws ServiceException {
+        this.manager = aManager;
+        this.storeJanitor = (StoreJanitor) this.manager.lookup(StoreJanitor.ROLE);
+    }
+
+    /**
+     * Configure the store. The following options can be used:
+     * <ul>
+     *  <li><code>maxobjects</code> (10000) - The maximum number of in-memory
objects.</li>
+     *  <li><code>overflow-to-disk</code> (true) - Whether to spool elements
to disk after
+     *   maxobjects has been exceeded.</li>
+     *  <li><code>use-cache-directory</code> (false) - If true the <i>cache-directory</i>
+     *   context entry will be used as the location of the disk store. 
+     *   Within the servlet environment this is set in web.xml.</li>
+     *  <li><code>use-work-directory</code> (false) - If true the <i>work-directory</i>
+     *   context entry will be used as the location of the disk store.
+     *   Within the servlet environment this is set in web.xml.</li>
+     *  <li><code>directory</code> - Specify an alternative location of
the disk store.
+     * </ul>
+     */
+    public void parameterize(Parameters parameters) throws ParameterException {
+
+        this.maxObjects = parameters.getParameterAsInteger("maxobjects", 10000);
+        this.overflowToDisk = parameters.getParameterAsBoolean("overflow-to-disk", true);
+
+        try {
+            if (parameters.getParameterAsBoolean("use-cache-directory", false)) {
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using cache directory: " + cacheDir);
+                }
+                setDirectory(cacheDir);
+            }
+            else if (parameters.getParameterAsBoolean("use-work-directory", false)) {
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using work directory: " + workDir);
+                }
+                setDirectory(workDir);
+            }
+            else if (parameters.getParameter("directory", null) != null) {
+                String dir = parameters.getParameter("directory");
+                dir = IOUtils.getContextFilePath(workDir.getPath(), dir);
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using directory: " + dir);
+                }
+                setDirectory(new File(dir));
+            }
+            else {
+                try {
+                    // Legacy: use working directory by default
+                    setDirectory(workDir);
+                } catch (IOException e) {
+                }
+            }
+        } catch (IOException e) {
+            throw new ParameterException("Unable to set directory", e);
+        }
+
+    }
+
+    /**
+     * Sets the cache directory
+     */
+    private void setDirectory(final File directory) throws IOException  {
+        
+        /* Save directory path prefix */
+        String directoryPath = getFullFilename(directory);
+        directoryPath += File.separator;
+
+        /* If directory doesn't exist, create it anew */
+        if (!directory.exists()) {
+            if (!directory.mkdir()) {
+                throw new IOException("Error creating store directory '" + directoryPath
+ "': ");
+            }
+        }
+
+        /* Is given file actually a directory? */
+        if (!directory.isDirectory()) {
+            throw new IOException("'" + directoryPath + "' is not a directory");
+        }
+
+        /* Is directory readable and writable? */
+        if (!(directory.canRead() && directory.canWrite())) {
+            throw new IOException("Directory '" + directoryPath + "' is not readable/writable");
+        }
+
+        System.setProperty("java.io.tmpdir", directoryPath);
+    }
+
+    /**
+     * Get the complete filename corresponding to a (typically relative)
+     * <code>File</code>.
+     * This method accounts for the possibility of an error in getting
+     * the filename's <i>canonical</i> path, returning the io/error-safe
+     * <i>absolute</i> form instead
+     *
+     * @param file The file
+     * @return The file's absolute filename
+     */
+    private static String getFullFilename(File file) {
+        try {
+            return file.getCanonicalPath();
+        }
+        catch (Exception e) {
+            return file.getAbsolutePath();
+        }
+    }
+
+    /**
+     * Initialize the CacheManager and created the Cache.
+     */
+    public void initialize() throws Exception {
+        URL configFileURL = Thread.currentThread().getContextClassLoader().getResource(CONFIG_FILE);
+        this.cacheManager = CacheManager.create(configFileURL);
+        this.cache = new Cache(this.cacheName, this.maxObjects, this.overflowToDisk, true,
0, 0, true, 120);
+        this.cacheManager.addCache(this.cache);
+        this.storeJanitor.register(this);
+    }
+    
+    /**
+     * Shutdown the CacheManager.
+     */
+    public void dispose() {
+        if (this.storeJanitor != null) {
+            this.storeJanitor.unregister(this);
+            this.manager.release(this.storeJanitor);
+            this.storeJanitor = null;
+        }
+        this.manager = null;
+        this.cacheManager.shutdown();
+        this.cacheManager = null;
+        this.cache = null;
+    }
+    
+    // ---------------------------------------------------- Store implementation
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#free()
+     */
+    public Object get(Object key) {
+        Object value = null;
+        try {
+            final Element element = this.cache.get((Serializable) key);
+            if (element != null) {
+                value = element.getValue();
+            }
+        }
+        catch (CacheException e) {
+            getLogger().error("Failure retrieving object from store", e);
+        }
+        if (getLogger().isDebugEnabled()) {
+            if (value != null) {
+                getLogger().debug("Found key: " + key);
+            } 
+            else {
+                getLogger().debug("NOT Found key: " + key);
+            }
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#free()
+     */
+    public void store(Object key, Object value) throws IOException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Store object " + value + " with key "+ key);
+        }
+        final Element element = new Element((Serializable) key, (Serializable) value);
+        this.cache.put(element);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#free()
+     */
+    public void free() {
+        try {
+            final List keys = this.cache.getKeysNoDuplicateCheck();
+            if (!keys.isEmpty()) {
+            	// TODO find a way to get to the LRU one.
+                final Serializable key = (Serializable) keys.get(0);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Freeing cache");
+                    getLogger().debug("key: " + key);
+                    getLogger().debug("value: " + this.cache.get(key));
+                }
+                if (!this.cache.remove(key)) {
+                    if (getLogger().isInfoEnabled()) {
+                        getLogger().info("Concurrency condition in free()");
+                    }
+                }
+            }
+        }
+        catch (CacheException e) {
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("Error in free()", e);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#remove(java.lang.Object)
+     */
+    public void remove(Object key) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Removing item " + key);
+        }
+        this.cache.remove((Serializable) key);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#clear()
+     */
+    public void clear() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Clearing the store");
+        }
+        try {
+            this.cache.removeAll();
+        }
+        catch (IOException e) {
+            getLogger().error("Failure to clearing store", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#containsKey(java.lang.Object)
+     */
+    public boolean containsKey(Object key) {
+        try {
+            return this.cache.get((Serializable) key) != null;
+        }
+        catch (CacheException e) {
+            getLogger().error("Failure retrieving object from store",e);
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#keys()
+     */
+    public Enumeration keys() {
+        List keys = null;
+        try {
+            keys = this.cache.getKeys();
+        }
+        catch (CacheException e) {
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("Error while getting cache keys", e);
+            }
+            keys = Collections.EMPTY_LIST;
+        }
+        return Collections.enumeration(keys);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#size()
+     */
+    public int size() {
+        try {
+            return this.cache.getSize();
+        }
+        catch (CacheException e) {
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("Error while getting cache size", e);
+            }
+            return 0;
+        }
+    }
+
+}

Added: cocoon/trunk/src/java/org/apache/cocoon/components/store/impl/ehcache.xml
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/store/impl/ehcache.xml	Wed Oct 20 06:29:36
2004
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<ehcache>
+
+    <!-- Sets the path to the directory where cache .data files are created.
+
+         If the path is a Java System Property it is replaced by
+         its value in the running VM.
+
+         The following properties are translated:
+         user.home - User's home directory
+         user.dir - User's current working directory
+         java.io.tmpdir - Default temp file path -->
+    <diskStore path="java.io.tmpdir"/>
+
+    <!--Default Cache configuration. These will be applied to caches programmatically
created through
+        the CacheManager.
+
+        The following attributes are required:
+
+        maxElementsInMemory            - Sets the maximum number of objects that will be
created in memory
+        eternal                        - Sets whether elements are eternal. If eternal, 
timeouts are ignored and the
+                                         element is never expired.
+        overflowToDisk                 - Sets whether elements can overflow to disk when
the in-memory cache
+                                         has reached the maxInMemory limit.
+
+        The following attributes are optional:
+        timeToIdleSeconds              - Sets the time to idle for an element before it expires.
+                                         i.e. The maximum amount of time between accesses
before an element expires
+                                         Is only used if the element is not eternal.
+                                         Optional attribute. A value of 0 means that an Element
can idle for infinity.
+                                         The default value is 0.
+        timeToLiveSeconds              - Sets the time to live for an element before it expires.
+                                         i.e. The maximum time between creation time and
when an element expires.
+                                         Is only used if the element is not eternal.
+                                         Optional attribute. A value of 0 means that and
Element can live for infinity.
+                                         The default value is 0.
+        diskPersistent                 - Whether the disk store persists between restarts
of the Virtual Machine.
+                                         The default value is false.
+        diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry
thread. The default value
+                                         is 120 seconds.
+        -->
+
+    <defaultCache
+        maxElementsInMemory="10000"
+        eternal="true"
+        timeToIdleSeconds="0"
+        timeToLiveSeconds="0"
+        overflowToDisk="true"
+        diskPersistent="true"
+        diskExpiryThreadIntervalSeconds="120"
+        />
+
+</ehcache>

Modified: cocoon/trunk/src/webapp/WEB-INF/cocoon.xconf
==============================================================================
--- cocoon/trunk/src/webapp/WEB-INF/cocoon.xconf	(original)
+++ cocoon/trunk/src/webapp/WEB-INF/cocoon.xconf	Wed Oct 20 06:29:36 2004
@@ -176,7 +176,7 @@
     <component-instance logger="core.modules.input" name="cocoon-properties" class="org.apache.cocoon.components.modules.input.PropertiesFileModule">
       <file src="resource://org/apache/cocoon/cocoon.properties" />
     </component-instance>
-    <component-instance logger="core.modules.input" name="flow-attr"     class="org.apache.cocoon.components.modules.input.FlowAttributeModule"/>
+    <component-instance logger="core.modules.input" name="flow-attribute"     class="org.apache.cocoon.components.modules.input.FlowAttributeModule"/>
     <component-instance logger="core.modules.input" name="flow-continuation"  class="org.apache.cocoon.components.modules.input.FlowContinuationModule"/>
 
     <component-instance logger="core.modules.input" name="xmlmeta"      class="org.apache.cocoon.components.modules.input.XMLMetaModule"/>
@@ -192,7 +192,6 @@
       <input-module name="defaults"/>
     </component-instance>
 
-
     <!-- The 'defaults', 'myxml' and 'slashdot' input modules are used
          in the samples -->
     <component-instance logger="core.modules.input" name="defaults"     class="org.apache.cocoon.components.modules.input.DefaultsModule">
@@ -201,6 +200,7 @@
         <base-url>http://localhost:8080/cocoon</base-url>
       </values>
     </component-instance>
+
     <component-instance class="org.apache.cocoon.components.modules.input.XMLFileModule"
logger="core.modules.xml" name="myxml">
       <file src="context://samples/modules/forrestconf.xml"/>
     </component-instance>
@@ -443,7 +443,7 @@
   
   <!--+
       | Store: generic store. The default implementation is an in-memory store
-      | backed by a disk store (based on JCS). This forms a two-stage
+      | backed by a disk store (based on EHCache). This forms a two-stage
       | cache composed of a fast in-memory MRU front-end and a persistent
       | back-end which stores the less-used objects.
       |

Mime
View raw message