[ajax4jsf-svn-commits] JBoss Ajax4JSF SVN: r146 - in trunk: framework/src/main/java/org/ajax4jsf/cache and 5 other directories.

ajax4jsf-svn-commits at lists.jboss.org ajax4jsf-svn-commits at lists.jboss.org
Tue May 1 21:14:48 EDT 2007


Author: nbelaevski
Date: 2007-05-01 21:14:48 -0400 (Tue, 01 May 2007)
New Revision: 146

Added:
   trunk/framework/src/main/java/org/ajax4jsf/cache/
   trunk/framework/src/main/java/org/ajax4jsf/cache/Cache.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/CacheEntry.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/CacheException.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/CacheFactory.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/CacheListener.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/CacheLoader.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/CacheManager.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCache.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCacheFactory.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCache.java
   trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCacheFactory.java
   trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CacheKey.java
   trunk/framework/src/test/java/org/ajax4jsf/cache/
   trunk/framework/src/test/java/org/ajax4jsf/cache/LRUMapCacheThreadedTest.java
Modified:
   trunk/framework/src/main/java/org/ajax4jsf/framework/ajax/xmlfilter/CacheContent.java
   trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CachedResourceContext.java
   trunk/framework/src/main/java/org/ajax4jsf/framework/resource/InternetResourceService.java
   trunk/test/src/test/java/org/ajax4jsf/framework/resource/InternetResourceServiceTestCase.java
Log:
Switching from OsCache to pluggable caches based on modified JSR-107 API has started

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/Cache.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/Cache.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/Cache.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,180 @@
+package org.ajax4jsf.cache;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * <p>
+ *    A cache, being a mechanism for efficient temporary storage of objects
+ * for the purpose of improving the overall performance of an application
+ * system, should not be necessary for the application to function correctly,
+ * it only improves the performance.
+ * <p>
+ *    A cache could be scoped, for examples to a JVM, all JVMs on a node, all
+ * nodes in a cluster, etc. Operations that are scoped to a cache such as put
+ * or load would affect all JVMs in the cache.  So the object loaded in 1 JVM
+ * would be equally available to all other JVMs in the cache.
+ * <p>
+ *   Objects are identified in the cache by a key. A key can be any Java
+ * object that implements the equals and  hashcode methods. If the object is
+ * to be distributed or persisted (if supported) it must implement
+ * serializable.
+ * <p/>
+ *   Each object in the cache will have a <code>CacheEntry<code> object associated with
+ * it. This object will encapsulate the metadata associated with the cached
+ * object. Mainly it represents the object statistics.
+ * <p/>
+ *   "CacheStatistics" represents the read-only statistics of the cache,
+ * while "CacheAttributes" represents the user settable attributes of the
+ * cache.
+ */
+public interface Cache
+{
+    /**
+     * Returns true if the cache contains the specified key.  The search is
+     * scoped to the cache. Other caches in the system will not be searched
+     * and a CacheLoader will not be called.
+     * @return true, if the cache contains the specified key.
+     */
+    public boolean containsKey(Object key);
+
+    /**
+     * @return true if the cache contains one or more keys to the specified value.
+     */
+    public boolean containsValue(Object value);
+
+    /**
+     * Returns a set view of the objects currently contained in the cache.
+     * A CacheLoader will not be called. The behavior is unspecified for the
+     * case when an object is remove from the cache while the return set is
+     * being traversed.
+     */
+    public Set entrySet();
+
+    /**
+     * Equality is based on the Set returned by entrySet.  Equal will return
+     * true if the two objects are referencing the same object or
+     * entrySet.equals(((Map)o).entrySet()) returns true.
+     */
+    public boolean equals(Object o);
+
+    /**
+     * @param ht a hashtable which holds a pointer pointing to the
+     * declarative cache description.
+     * @throws CacheException if any error occurs.
+     */
+
+    /**
+     * @return the hash code value for this the cache.
+     */
+    public int hashCode();
+
+    /**
+     * @return true if entrySet().isEmpty() returns true.
+     */
+    public boolean isEmpty();
+
+    /**
+     * Returns a set view of the keys currently contained in the cache.  A
+     * CacheLoader will not be called. The behavior is unspecified for the
+     * case when an object is remove from the cache while the return set is
+     * being traversed.
+     */
+    public Set keySet();
+
+    /**
+     * Copies all of the mappings from the specified map to the cache.  This
+     * would be equivalent to t.entrySet() then iterating through the Set and
+     * calling put with each key value pair.
+     */
+    public void putAll(Map t);
+
+    /**
+     * @return the number of objects in the cache. This should be the same
+     * value as entrySet().size();
+     */
+    public int size();
+
+    /**
+     * @return a collection view of the values contained in the cache.
+     */
+    public Collection values();
+
+    /**
+     * The get method will return, from the cache, the object associated with
+     * the argument "key". If the object is not in the cache, the associated
+     * cache loader will be called. If no loader is associated with the object,
+     * a null is returned.  If a problem is encountered during the retrieving
+     * or loading of the object, an exception (to be defined) will be thrown.
+     * If the "arg" argument is set, the arg object will be passed to the
+     * CacheLoader.load method.  The cache will not dereference the object.
+     * If no "arg" value is provided a null will be passed to the load method.
+     * The storing of null values in the cache is permitted, however, the get
+     * method will not distinguish returning a null stored in the cache and
+     * not finding the object in the cache. In both cases a null is returned.
+     * @throws CacheException 
+     */
+    public Object get(Object key, Object context) throws CacheException;
+
+    /**
+     * The load method provides a means to "pre load" the cache. This method
+     * will, asynchronously, load the specified object into the cache using
+     * the associated cacheloader. If the object already exists in the cache,
+     * no action is taken. If no loader is associated with the object, no object
+     * will be loaded into the cache.  If a problem is encountered during the
+     * retrieving or loading of the object, an exception should
+     * be logged.
+     * If the "arg" argument is set, the arg object will be passed to the
+     * CacheLoader.load method.  The cache will not dereference the object. If
+     * no "arg" value is provided a null will be passed to the load method.
+     * The storing of null values in the cache is permitted, however, the get
+     * method will not distinguish returning a null stored in the cache and not
+     * finding the object in the cache. In both cases a null is returned.
+     */
+    public void load(Object key, Object context) throws CacheException;
+
+    /**
+     * The peek method will return the object associated with "key" if it
+     * currently exists (and is valid) in the cache. If not, a null is
+     * returned.  With "peek" the CacheLoader will not be invoked and other
+     * caches in the system will not be searched.
+     */
+    public Object peek(Object key);
+
+    /**
+     * The put method adds the object "value" to the cache identified by the
+     * object "key".
+     */
+    public Object put(Object key, Object value);
+
+    /**
+     * Returns the CacheEntry object associated with the object identified by
+     * "key". If the object is not in the cache a null is returned.
+     */
+    public CacheEntry getCacheEntry(Object key);
+
+    /**
+     * The remove method will delete the object from the cache including the
+     * key, the associated value and the associated CacheStatistics object.
+     */
+    public Object remove(Object key);
+
+    /**
+     * The clear method will remove all objects from the cache including the
+     * key, the associated value and the associated CacheStatistics object.
+     */
+    public void clear();
+
+    /**
+     * The evict method will remove objects from the cache that are no longer
+     * valid.  Objects where the specified expiration time has been reached.
+     */
+    public void evict();
+
+    /** Add a listener to the list of cache listeners */
+    public void addListener(CacheListener listener);
+
+    /** Remove a listener from the list of cache listeners */
+    public void removeListener(CacheListener listener);
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/CacheEntry.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/CacheEntry.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/CacheEntry.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,29 @@
+package org.ajax4jsf.cache;
+
+import java.util.Map;
+
+/**
+ * CacheEntry
+ *
+ * @author Brian Goetz
+ */
+public interface CacheEntry extends Map.Entry {
+
+    int getHits();
+
+    long getLastAccessTime();
+    long getLastUpdateTime();
+    long getCreationTime();
+    long getExpirationTime();
+
+    /**
+     * Returns a version counter.
+     * An implementation may use timestamps for this or an incrementing
+     * number. Timestamps usually have issues with granularity and are harder
+     * to use across clusteres or threads, so an incrementing counter is often safer.
+     */
+    long getVersion();
+
+    boolean isValid();
+    long getCost();
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/CacheException.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/CacheException.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/CacheException.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,43 @@
+package org.ajax4jsf.cache;
+
+
+/**
+ * CacheException is a generic exception, which indicates
+ * a cache error has occurred. All the other cache exceptions are the
+ * subclass of this class. All the methods in the cache package only
+ * throw CacheException or the sub class of it.
+ * <P>
+ *
+ */
+public class CacheException extends Exception
+{
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 6712594794189413065L;
+
+	/**
+     * Constructs a new CacheException.
+     */
+    public CacheException()
+    {
+        super();
+    }
+
+    /**
+     * Constructs a new CacheException with a message string.
+     */
+    public CacheException(String s)
+    {
+        super(s);
+    }
+
+    /**
+     * Constructs a CacheException with a message string, and
+     * a base exception
+     */
+    public CacheException(String s, Throwable ex)
+    {
+        super(s, ex);
+    }
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/CacheFactory.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/CacheFactory.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/CacheFactory.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,21 @@
+package org.ajax4jsf.cache;
+
+import java.util.Map;
+
+/**
+ * CacheFactory is a service provider specific interface.
+ * Service provider should implement CacheFactory to provide
+ * the functionality to create a new implementation specific Cache object.
+ */
+public interface CacheFactory
+{
+    /**
+     * creates a new implementation specific Cache object using the env parameters.
+     * @param env implementation specific environment parameters passed to the
+     * CacheFactory.
+     * @param cacheLoader implementation of the {@link CacheLoader} to use
+     * @return an implementation specific Cache object.
+     * @throws CacheException if any error occurs.
+     */
+    public Cache createCache(Map env, CacheLoader cacheLoader) throws CacheException;
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/CacheListener.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/CacheListener.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/CacheListener.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,20 @@
+package org.ajax4jsf.cache;
+
+/** Interface describing various events that can happen as elements are added to
+ *  or removed from a cache
+ */
+public interface CacheListener {
+    /** Triggered when a cache mapping is created due to the cache loader being consulted */
+    public void onLoad(Object key);
+
+    /** Triggered when a cache mapping is created due to calling Cache.put() */
+    public void onPut(Object key);
+
+    /** Triggered when a cache mapping is removed due to eviction */
+    public void onEvict(Object key);
+
+    /** Triggered when a cache mapping is removed due to calling Cache.remove() */
+    public void onRemove(Object key);
+
+    public void onClear();
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/CacheLoader.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/CacheLoader.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/CacheLoader.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,24 @@
+package org.ajax4jsf.cache;
+
+
+/**
+ * User should implement this CacheLoader interface to
+ * provide a loader object to load the objects into cache.
+ */
+public interface CacheLoader
+{
+    /**
+     * loads an object. Application writers should implement this
+     * method to customize the loading of cache object. This method is called
+     * by the caching service when the requested object is not in the cache.
+     * <P>
+     *
+     * @param key the key identifying the object being loaded
+     *
+     * @return The object that is to be stored in the cache.
+     * @throws CacheException
+     *
+     */
+    public Object load(Object key, Object context) throws CacheException;
+
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/CacheManager.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/CacheManager.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/CacheManager.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,113 @@
+package org.ajax4jsf.cache;
+
+import java.io.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * CacheManager is used in J2SE environments for looking up named caches.
+ */
+public class CacheManager {
+
+    private static final String FACTORY_PROPERTY_NAME = "org.ajax4jsf.cache.CacheFactory";
+    private static final String DEFAULT_FACTORY_NAME = "org.ajax4jsf.cache.OSCacheCacheFactory";
+
+    protected static CacheManager instance = new CacheManager();
+
+    // REVIEW brian at quiotix.com
+    // Should this be a HashMap<String, WeakReference<Cache>>?
+    private final Map caches = Collections.synchronizedMap(new HashMap());
+
+    /**
+     * Returns the singleton CacheManager
+     */
+    public static CacheManager getInstance() {
+        return instance;
+    }
+
+    public Cache getCache(String cacheName) {
+        return (Cache) caches.get(cacheName);
+    }
+
+    public void registerCache(String cacheName, Cache cache) {
+        caches.put(cacheName, cache);
+    }
+
+    public CacheFactory getCacheFactory() throws CacheException {
+        String factoryName = findFactory(FACTORY_PROPERTY_NAME);
+
+        try {
+            ClassLoader cl = findClassLoader();
+            Class spiClass = Class.forName(factoryName, true, cl);
+            return (CacheFactory) spiClass.newInstance();
+        } catch (ClassNotFoundException cnfe) {
+            throw new CacheException("Could not find class: '" + factoryName + "'");
+        } catch (ClassCastException cce) {
+            throw new CacheException("Class: '" + factoryName + "' does not implement CacheFactory");
+        } catch (InstantiationException ie) {
+            throw new CacheException("Could not instantiate: '" + factoryName + "'");
+        } catch (IllegalAccessException iae) {
+            throw new CacheException("Could not find public default constructor for: '" + factoryName + "'");
+        }
+    }
+
+    private  ClassLoader findClassLoader() {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if (cl == null) cl = ClassLoader.getSystemClassLoader();
+        return cl;
+    }
+
+    private  boolean isEmptyString(String s) {
+        return s == null || "".equals(s);
+    }
+
+    String findFactory(String factoryId) {
+
+        // Use the system property first
+        try {
+            String factoryClass = System.getProperty(factoryId);
+            if (!isEmptyString(factoryClass)) return factoryClass;
+        } catch (SecurityException ignore) {
+        }
+
+        // try to read from $java.home/lib/jcache.properties
+        try {
+            String configFile = System.getProperty("java.home") +
+                    File.separator + "lib" + File.separator + "jcache.properties";
+            File f = new File(configFile);
+            if (f.exists()) {
+                InputStream in = new FileInputStream(f);
+                try {
+                    Properties props = new Properties();
+                    props.load(in);
+                    String factoryClass = props.getProperty(factoryId);
+                    if (!isEmptyString(factoryClass)) return factoryClass;
+                } finally {
+                    in.close();
+                }
+            }
+        } catch (SecurityException ignore) {
+        } catch (IOException ignore) {
+        }
+
+        // try to find services in CLASSPATH
+        try {
+            ClassLoader cl = findClassLoader();
+            InputStream is = cl.getResourceAsStream("META-INF/services/" + factoryId);
+            if (is != null) {
+                BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+                try {
+                    String factoryName = r.readLine();
+                    if (!isEmptyString(factoryName)) return factoryName;
+                } finally {
+                    r.close();
+                }
+            }
+        } catch (IOException ignore) {
+        }
+
+        return DEFAULT_FACTORY_NAME;
+    }
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCache.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCache.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCache.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,120 @@
+/**
+ * 
+ */
+package org.ajax4jsf.cache;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.collections.map.LRUMap;
+
+/**
+ * @author Nick - mailto:nbelaevski at exadel.com
+ * created 01.05.2007
+ * 
+ */
+public class LRUMapCache extends LRUMap implements Cache {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 3236528957956574490L;
+	private CacheLoader cacheLoader;
+
+	public LRUMapCache(CacheLoader cacheLoader, int initialSize) {
+		super(initialSize);
+		this.cacheLoader = cacheLoader;
+	}
+
+	public LRUMapCache(CacheLoader cacheLoader) {
+		super();
+		this.cacheLoader = cacheLoader;
+	}
+
+	public void addListener(CacheListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void evict() {
+		// TODO Auto-generated method stub
+
+	}
+
+	private Map futures = new HashMap();
+
+	public Object get(Object key, Object context) throws CacheException {
+
+		try {
+			LRUMapFuture activeFuture = null;
+			LRUMapFuture future = null;
+
+			synchronized (this) {
+				future = (LRUMapFuture) futures.get(key);
+				if (future == null) {
+					activeFuture = new LRUMapFuture();
+					futures.put(key, activeFuture);
+				}
+
+			}
+
+			if (future != null) {
+				synchronized (future) {
+					future.wait();
+					return future.getResult();
+				}
+			} else {
+				synchronized (this) {
+					synchronized (activeFuture) {
+						try {
+							if (!containsKey(key)) {
+								load(key, context);
+							}
+
+							Object result = peek(key);
+							activeFuture.setResult(result);
+
+							return result;
+						} finally {
+							this.futures.remove(key);
+							activeFuture.notifyAll();
+						}
+					}
+				}
+			}
+
+		} catch (InterruptedException e) {
+			throw new CacheException(e.getMessage(), e);
+		}
+	}
+
+	public CacheEntry getCacheEntry(Object key) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public synchronized void load(Object key, Object context) throws CacheException {
+		put(key, cacheLoader.load(key, context));
+	}
+
+	public synchronized Object peek(Object key) {
+		return this.get(key);
+	}
+
+	public void removeListener(CacheListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+}
+
+class LRUMapFuture {
+	private Object result;
+
+	public Object getResult() {
+		return result;
+	}
+
+	public void setResult(Object result) {
+		this.result = result;
+	}
+}
\ No newline at end of file

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCacheFactory.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCacheFactory.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/LRUMapCacheFactory.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,21 @@
+/**
+ * 
+ */
+package org.ajax4jsf.cache;
+
+import java.util.Map;
+
+
+/**
+ * @author Nick - mailto:nbelaevski at exadel.com
+ * created 01.05.2007
+ * 
+ */
+public class LRUMapCacheFactory implements CacheFactory {
+
+	public Cache createCache(Map env, CacheLoader cacheLoader)
+			throws CacheException {
+		return new LRUMapCache(cacheLoader);
+	}
+
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCache.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCache.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCache.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,196 @@
+/**
+ * 
+ */
+package org.ajax4jsf.cache;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+
+import com.opensymphony.oscache.base.NeedsRefreshException;
+
+/**
+ * @author Nick - mailto:nbelaevski at exadel.com
+ * created 01.05.2007
+ * 
+ */
+public class OSCacheCache implements Cache {
+
+	private com.opensymphony.oscache.base.Cache cache;
+	private CacheLoader cacheLoader;
+
+	public OSCacheCache(com.opensymphony.oscache.base.Cache cache,
+			CacheLoader cacheLoader) {
+		super();
+		this.cache = cache;
+		this.cacheLoader = cacheLoader;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#addListener(org.ajax4jsf.framework.resource.cache.CacheListener)
+	 */
+	public void addListener(CacheListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#clear()
+	 */
+	public void clear() {
+		// TODO Auto-generated method stub
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#containsKey(java.lang.Object)
+	 */
+	public boolean containsKey(Object key) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#containsValue(java.lang.Object)
+	 */
+	public boolean containsValue(Object value) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#entrySet()
+	 */
+	public Set entrySet() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#evict()
+	 */
+	public void evict() {
+		// TODO Auto-generated method stub
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#get(java.lang.Object, java.lang.Object)
+	 */
+	public Object get(Object key, Object context) throws CacheException {
+		String keyString = key.toString();
+
+		try {
+			return cache.getFromCache(keyString);
+		} catch (NeedsRefreshException e) {
+			Object object = cacheLoader.load(key, context);
+			try {
+				cache.putInCache(keyString, object);
+			} catch (Exception e1) {
+				cache.cancelUpdate(keyString);
+				throw new CacheException(e1.getMessage(), e1);
+			}
+			return object;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#getCacheEntry(java.lang.Object)
+	 */
+	public CacheEntry getCacheEntry(Object key) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#isEmpty()
+	 */
+	public boolean isEmpty() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#keySet()
+	 */
+	public Set keySet() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#load(java.lang.Object, java.lang.Object)
+	 */
+	public void load(Object key, Object context) throws CacheException {
+		cacheLoader.load(key, context);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#peek(java.lang.Object)
+	 */
+	public Object peek(Object key) {
+		String keyString = key.toString();
+
+		try {
+			return cache.getFromCache(keyString);
+		} catch (NeedsRefreshException e) {
+			cache.cancelUpdate(keyString);
+		}
+
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#put(java.lang.Object, java.lang.Object)
+	 */
+	public Object put(Object key, Object value) {
+		cache.putInCache(key.toString(), value);
+		return value;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#putAll(java.util.Map)
+	 */
+	public void putAll(Map t) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#remove(java.lang.Object)
+	 */
+	public Object remove(Object key) {
+		String keyString = key.toString();
+
+		try {
+			return this.peek(keyString);
+		} finally {
+			cache.removeEntry(keyString);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#removeListener(org.ajax4jsf.framework.resource.cache.CacheListener)
+	 */
+	public void removeListener(CacheListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#size()
+	 */
+	public int size() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.Cache#values()
+	 */
+	public Collection values() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

Added: trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCacheFactory.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCacheFactory.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/cache/OSCacheCacheFactory.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,27 @@
+/**
+ * 
+ */
+package org.ajax4jsf.cache;
+
+import java.util.Map;
+
+
+import com.opensymphony.oscache.general.GeneralCacheAdministrator;
+
+/**
+ * @author Nick - mailto:nbelaevski at exadel.com
+ * created 01.05.2007
+ * 
+ */
+public class OSCacheCacheFactory implements CacheFactory {
+
+	/* (non-Javadoc)
+	 * @see org.ajax4jsf.framework.resource.cache.CacheFactory#createCache(java.util.Map, org.ajax4jsf.framework.resource.cache.CacheLoader)
+	 */
+	public Cache createCache(Map env, CacheLoader cacheLoader)
+			throws CacheException {
+		GeneralCacheAdministrator cacheAdministrator = new GeneralCacheAdministrator();
+		return new OSCacheCache(cacheAdministrator.getCache(), cacheLoader);
+	}
+
+}

Modified: trunk/framework/src/main/java/org/ajax4jsf/framework/ajax/xmlfilter/CacheContent.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/framework/ajax/xmlfilter/CacheContent.java	2007-05-01 01:27:27 UTC (rev 145)
+++ trunk/framework/src/main/java/org/ajax4jsf/framework/ajax/xmlfilter/CacheContent.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -172,7 +172,7 @@
          * @param responseStream
          * @return
          */
-    public OutputStream getOutputStream(final OutputStream responseStream) {
+    public OutputStream getOutputStream() {
 	if (null == servletStream) {
 	    outputStream = new FastBufferOutputStream(1024);
 	    servletStream = new ServletOutputStream() {
@@ -185,7 +185,6 @@
 		public void close() throws IOException {
 		    filledOutputStream = true;
 		    // / content = outputStream.toByteArray();
-		    responseStream.close();
 		    content = null;
 		}
 
@@ -195,7 +194,6 @@
                  * @see java.io.OutputStream#flush()
                  */
 		public void flush() throws IOException {
-		    responseStream.flush();
 		}
 
 		/*
@@ -206,7 +204,6 @@
 		public void write(byte[] b, int off, int len)
 			throws IOException {
 		    outputStream.write(b, off, len);
-		    responseStream.write(b, off, len);
 		}
 
 		/*
@@ -216,12 +213,10 @@
                  */
 		public void write(byte[] b) throws IOException {
 		    outputStream.write(b);
-		    responseStream.write(b);
 		}
 
 		public void write(int b) throws IOException {
 		    outputStream.write(b);
-		    responseStream.write(b);
 		}
 
 	    };
@@ -229,23 +224,20 @@
 	return servletStream;
     }
 
-    public PrintWriter getWriter(final Writer responseWriter) {
+    public PrintWriter getWriter() {
 	if (null == servletWriter) {
 	    stringOutputWriter = new FastBufferWriter(1024);
 	    Writer out = new Writer() {
 
 		public void write(char[] cbuf, int off, int len)
 			throws IOException {
-		    responseWriter.write(cbuf, off, len);
 		    stringOutputWriter.write(cbuf, off, len);
 		}
 
 		public void flush() throws IOException {
-		    responseWriter.flush();
 		}
 
 		public void close() throws IOException {
-		    responseWriter.close();
 		    // / writerContent = stringOutputWriter.toString();
 		    filledOutputWriter = true;
 		    writerContent = null;

Added: trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CacheKey.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CacheKey.java	                        (rev 0)
+++ trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CacheKey.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,41 @@
+/**
+ * 
+ */
+package org.ajax4jsf.framework.resource;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author Nick - mailto:nbelaevski at exadel.com
+ * created 01.05.2007
+ * 
+ */
+public class CacheKey {
+	private Object resourceData;
+	private HttpServletRequest request;
+    private HttpServletResponse response;
+    private InternetResource resource;
+	public CacheKey(Object resourceData,
+			HttpServletRequest request, HttpServletResponse response,
+			InternetResource resource) {
+		super();
+		this.resourceData = resourceData;
+		this.request = request;
+		this.response = response;
+		this.resource = resource;
+	}
+	public Object getResourceData() {
+		return resourceData;
+	}
+	public HttpServletRequest getRequest() {
+		return request;
+	}
+	public HttpServletResponse getResponse() {
+		return response;
+	}
+	public InternetResource getResource() {
+		return resource;
+	}
+	
+}

Modified: trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CachedResourceContext.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CachedResourceContext.java	2007-05-01 01:27:27 UTC (rev 145)
+++ trunk/framework/src/main/java/org/ajax4jsf/framework/resource/CachedResourceContext.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -51,7 +51,7 @@
 	 * @see org.ajax4jsf.framework.resource.ResourceContext#getOutputStream()
 	 */
 	public OutputStream getOutputStream() throws IOException {
-		return content.getOutputStream(this.parent.getOutputStream());
+		return content.getOutputStream();
 	}
 
 	/* (non-Javadoc)
@@ -94,7 +94,6 @@
 	 */
 	public void setDateHeader(String name, long value) {
 		this.content.setDateHeader(name,value);
-		this.parent.setDateHeader(name, value);
 	}
 
 	/* (non-Javadoc)
@@ -102,7 +101,6 @@
 	 */
 	public void setHeader(String name, String value) {
 		this.content.setHeader(name,value);
-		this.parent.setHeader(name, value);
 	}
 
 	/* (non-Javadoc)
@@ -110,7 +108,6 @@
 	 */
 	public void setIntHeader(String name, int value) {
 		this.content.setIntHeader(name,value);
-		this.parent.setIntHeader(name, value);
 	}
 
 	/**
@@ -124,17 +121,14 @@
 	 * @see org.ajax4jsf.framework.resource.ResourceContext#getWriter()
 	 */
 	public PrintWriter getWriter() throws IOException {
-		// TODO Auto-generated method stub
-		return content.getWriter(this.parent.getWriter());
+		return content.getWriter();
 	}
 
 	public void setContentType(String contentType) {
-		this.parent.setContentType(contentType);
 		this.content.setContentType(contentType);
 	}
 
 	public Object getResourceData() {
-		// TODO Auto-generated method stub
 		return parent.getResourceData();
 	}
 
@@ -148,13 +142,11 @@
 	}
 
 	public String getServletPath() {
-		// TODO Auto-generated method stub
 		return parent.getServletPath();
 	}
 	
 	public void release() {
 		super.release();
-		parent.release();
 	}
 	
 }

Modified: trunk/framework/src/main/java/org/ajax4jsf/framework/resource/InternetResourceService.java
===================================================================
--- trunk/framework/src/main/java/org/ajax4jsf/framework/resource/InternetResourceService.java	2007-05-01 01:27:27 UTC (rev 145)
+++ trunk/framework/src/main/java/org/ajax4jsf/framework/resource/InternetResourceService.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -23,7 +23,10 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Properties;
 
 import javax.faces.FacesException;
@@ -38,6 +41,10 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.ajax4jsf.cache.Cache;
+import org.ajax4jsf.cache.CacheException;
+import org.ajax4jsf.cache.CacheLoader;
+import org.ajax4jsf.cache.CacheManager;
 import org.ajax4jsf.framework.ajax.xmlfilter.BaseFilter;
 import org.ajax4jsf.framework.ajax.xmlfilter.CacheContent;
 import org.ajax4jsf.framework.util.config.WebXml;
@@ -45,11 +52,8 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import com.opensymphony.oscache.base.Cache;
-import com.opensymphony.oscache.base.NeedsRefreshException;
-import com.opensymphony.oscache.web.ServletCacheAdministrator;
 
-public class InternetResourceService {
+public class InternetResourceService implements CacheLoader {
     private static final Log log = LogFactory
 	    .getLog(InternetResourceService.class);
 
@@ -61,7 +65,9 @@
 
     private boolean cacheEnabled = true;
 
-    private ServletCacheAdministrator cacheAdmin;
+    private Cache cache = null;
+    
+    //private ServletCacheAdministrator cacheAdmin;
 
     private FacesContextFactory contextFactory;
 
@@ -88,13 +94,20 @@
 		.getInitParameter(ENABLE_CACHING_PARAMETER))) {
 	    setCacheEnabled(false);
 	    // this.cacheEnabled = false;
-	    this.cacheAdmin = null;
+	    //this.cacheAdmin = null;
 	} else {
 	    // Load our implementation properties
 	    Properties cacheProperties = getProperties("oscache.properties");
 	    cacheProperties.putAll(getProperties("/oscache.properties"));
-	    this.cacheAdmin = ServletCacheAdministrator.getInstance(
-		    servletContext, cacheProperties);
+	    //this.cacheAdmin = ServletCacheAdministrator.getInstance(
+		//    servletContext, cacheProperties);
+	    Map env = new HashMap();
+	    try {
+			this.cache = CacheManager.getInstance().getCacheFactory().createCache(env, this);
+		} catch (CacheException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
 	}
 	// Create Resource-specific Faces Lifecycle instance.
 	lifecycleClass = servletContext
@@ -169,48 +182,57 @@
 	    String cacheKey = resourceKey;// + "?" +
                                                 // request.getQueryString();
 	    // TODO - select session/application scope.
-	    Cache cache = cacheAdmin.getAppScopeCache(getServletContext());
-	    try {
+	    //Cache cache = cacheAdmin.getAppScopeCache(getServletContext());
+//	    try {
 		// TODO - use last modified/expires time
-		CacheContent content = (CacheContent) cache
-			.getFromCache(cacheKey);
-		if (log.isDebugEnabled()) {
-		    log.debug(Messages.getMessage(
-			    Messages.GET_CONTENT_FROM_CACHE_INFO, cacheKey));
-		}
-		content.sendHeaders(response);
-		// Correct expires date for resource.
-		Date expired = resource.getExpired(null);
-		if (expired != null) {
-		    response.setDateHeader("Expires", expired.getTime());
-		} else {
-		    response.setDateHeader("Expires", System
-			    .currentTimeMillis()
-			    + InternetResource.DEFAULT_EXPIRE);
-		}
-		if (!request.getMethod().equals("HEAD")) {
-		    content.send(response);
-		}
-	    } catch (NeedsRefreshException e) {
+		
+	    CacheKey key = new CacheKey(resourceDataForKey, request, response, resource);
+	    
+	    CacheContent content;
 		try {
-		    if (log.isDebugEnabled()) {
-			log.debug(Messages.getMessage(
-				Messages.CONTENT_NOT_FOUND_ERROR, cacheKey));
-		    }
-		    CachedResourceContext context = (CachedResourceContext) sendResource(
-			    resource, request, response, resourceDataForKey);
-		    // TODO - set refresh interval ?
-		    cache.putInCache(cacheKey, context.getContent());
-		} catch (Exception ex) {
-		    cache.cancelUpdate(cacheKey);
-		    log.error(
-			    Messages.getMessage(Messages.SEND_RESOURCE_ERROR),
-			    ex);
-		    throw new ServletException(Messages.getMessage(
-			    Messages.SEND_RESOURCE_ERROR_2, ex.getMessage()),
-			    ex);
+			content = (CacheContent) cache
+				.get(cacheKey, key);
+			if (log.isDebugEnabled()) {
+			    log.debug(Messages.getMessage(
+				    Messages.GET_CONTENT_FROM_CACHE_INFO, cacheKey));
+			}
+			content.sendHeaders(response);
+			// Correct expires date for resource.
+			Date expired = resource.getExpired(null);
+			if (expired != null) {
+			    response.setDateHeader("Expires", expired.getTime());
+			} else {
+			    response.setDateHeader("Expires", System
+				    .currentTimeMillis()
+				    + InternetResource.DEFAULT_EXPIRE);
+			}
+			if (!request.getMethod().equals("HEAD")) {
+			    content.send(response);
+			}/*
+		    } catch (NeedsRefreshException e) {
+			try {
+			    if (log.isDebugEnabled()) {
+				log.debug(Messages.getMessage(
+					Messages.CONTENT_NOT_FOUND_ERROR, cacheKey));
+			    }
+			    CachedResourceContext context = (CachedResourceContext) sendResource(
+				    resource, request, response, resourceDataForKey);
+			    // TODO - set refresh interval ?
+			    cache.put(cacheKey, context.getContent());
+			} catch (Exception ex) {
+			    //cache.cancelUpdate(cacheKey);
+			    log.error(
+				    Messages.getMessage(Messages.SEND_RESOURCE_ERROR),
+				    ex);
+			    throw new ServletException(Messages.getMessage(
+				    Messages.SEND_RESOURCE_ERROR_2, ex.getMessage()),
+				    ex);
+			}
+		    }*/
+		} catch (CacheException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
 		}
-	    }
 	} else {
 	    sendResource(resource, request, response, resourceDataForKey);
 	}
@@ -331,4 +353,31 @@
 	return resourceBuilder;
     }
 
+	public Object load(Object key, Object context) throws CacheException {
+		CacheKey cacheKey = (CacheKey) context;
+		
+		CachedResourceContext resourceContext = (CachedResourceContext) getResourceContext(cacheKey.getResource(), cacheKey.getRequest(),
+				cacheKey.getResponse());
+			resourceContext.setResourceData(cacheKey.getResourceData());
+			try {
+				getLifecycle().send(resourceContext, cacheKey.getResource());
+			} catch (FacesException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			resourceContext.release();
+
+		    // TODO - set refresh interval ?
+		    //cache.put(cacheKey, resourceContext.getContent());
+		return resourceContext.getContent();
+	}
+
+	public Map loadAll(Collection keys, Object context) throws CacheException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
 }

Added: trunk/framework/src/test/java/org/ajax4jsf/cache/LRUMapCacheThreadedTest.java
===================================================================
--- trunk/framework/src/test/java/org/ajax4jsf/cache/LRUMapCacheThreadedTest.java	                        (rev 0)
+++ trunk/framework/src/test/java/org/ajax4jsf/cache/LRUMapCacheThreadedTest.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -0,0 +1,75 @@
+/**
+ * 
+ */
+package org.ajax4jsf.cache;
+
+import java.util.Random;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Nick - mailto:nbelaevski at exadel.com
+ * created 02.05.2007
+ * 
+ */
+public class LRUMapCacheThreadedTest extends TestCase {
+	private CacheLoader cacheLoader = new CacheLoader() {
+
+		public Object load(Object key, Object context) throws CacheException {
+			try {
+				Thread.sleep(new Random().nextInt(100) + 1);
+			} catch (InterruptedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return key;
+		}
+	};
+	
+	private static final int COUNT = 2000;
+	
+	private final Cache cache = new LRUMapCache(cacheLoader, COUNT);
+
+	public void testCache() throws Exception {
+		Thread[] threads = new Thread[COUNT];
+		
+		try {
+			for (int i = 0; i < COUNT; i++) {
+				threads[i] = new TestThread(cache, new Integer(new Random().nextInt(10)));
+				threads[i].start();
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	
+		for (int i = 0; i < COUNT; i++) {
+			threads[i].join();
+		}
+	}
+}
+
+class TestThread extends Thread {
+	private Cache cache;
+	private Integer idx;
+	
+	public TestThread(Cache cache, Integer idx) {
+		super();
+		this.cache = cache;
+		this.idx = idx;
+	}
+	
+	public void run() {
+		super.run();
+
+		try {
+			if (!idx.equals(cache.get(idx, null))) {
+				throw new IllegalStateException();
+			} else {
+			//	System.out.println("TestThread.run(): " + idx);
+			}
+		} catch (CacheException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+}
\ No newline at end of file

Modified: trunk/test/src/test/java/org/ajax4jsf/framework/resource/InternetResourceServiceTestCase.java
===================================================================
--- trunk/test/src/test/java/org/ajax4jsf/framework/resource/InternetResourceServiceTestCase.java	2007-05-01 01:27:27 UTC (rev 145)
+++ trunk/test/src/test/java/org/ajax4jsf/framework/resource/InternetResourceServiceTestCase.java	2007-05-02 01:14:48 UTC (rev 146)
@@ -146,9 +146,6 @@
 		assertTrue("Resource was generated "+counter+" times", counter<= 10);
 	}
 	
-	/**
-	 * Test method for {@link org.ajax4jsf.framework.resource.InternetResourceService#sendResource(org.ajax4jsf.framework.resource.InternetResource, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}.
-	 */
 	public void testSendResource() {
 //		fail("Not yet implemented");
 	}




More information about the ajax4jsf-svn-commits mailing list