You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by jv...@locus.apache.org on 2000/11/16 02:46:58 UTC

cvs commit: jakarta-velocity/src/java/org/apache/velocity/util/cache CachedObject.java GlobalCache.java GlobalCacheService.java~ ObjectExpiredException.java Refreshable.java RefreshableCachedObject.java TurbineGlobalCacheService.java~

jvanzyl     00/11/15 17:46:58

  Added:       src/java/org/apache/velocity/util/cache CachedObject.java
                        GlobalCache.java GlobalCacheService.java~
                        ObjectExpiredException.java Refreshable.java
                        RefreshableCachedObject.java
                        TurbineGlobalCacheService.java~
  Log:
  - this a reworking of the turbine cache that i would eventually like
    to use in velocity and roll back into turbine. it's not being used
    right now but will be shortly. i would like to make it the cache
    accept permanent, expirable and refreshable objects. expand on what
    dave and nissim have done. right now i'm just using a hashtable
    for the cache in the runtime but i would soon like to use these
    files.
  
  Revision  Changes    Path
  1.1                  jakarta-velocity/src/java/org/apache/velocity/util/cache/CachedObject.java
  
  Index: CachedObject.java
  ===================================================================
  package org.apache.velocity.util.cache;
  
  /*
   * Copyright (c) 1997-2000 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
   *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
   *    "Java Apache Project" must not be used to endorse or promote products
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  // Java Core Classes
  //import java.util.*;
  
  /*
   * Wrapper for an object you want to store in a cache for a period of
   * time.
   *
   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
   * @version $Id: CachedObject.java,v 1.1 2000/11/16 01:46:58 jvanzyl Exp $
   */
  public class CachedObject implements java.io.Serializable
  {
      /** The object to be cached. */
      private Object contents = null;
  
      /** Default age (30 minutes). */
      //private long defaultage = TurbineResources.getLong("cachedobject.defaultage", 1800000);
      private long defaultage = 1800000L;
  
      /** When created. **/
      protected long created = 0;
  
      /** When it expires. **/
      private long expires = 0;
  
      /** Is this object stale/expired? */
      private boolean stale = false;
  
  
      /**
       * Constructor; sets the object to expire in the default time (30
       * minutes).
       *
       * @param o The object you want to cache.
       */
      public CachedObject(Object o)
      {
          this.contents = o;
          this.expires = defaultage;
          this.created = System.currentTimeMillis();
      }
  
      /**
       * Constructor.
       *
       * @param o The object to cache.
       * @param expires How long before the object expires, in ms,
       * e.g. 1000 = 1 second.
       */
      public CachedObject(Object o,
                          long expires)
      {
          if ( expires == 0 )
          {
              this.expires = defaultage;
          }
  
          this.contents = o;
          this.expires = expires;
          this.created = System.currentTimeMillis();
      }
  
      /**
       * Returns the cached object.
       *
       * @return The cached object.
       */
      public Object getContents()
      {
          return contents;
      }
  
      /**
       * Returns the creation time for the object.
       *
       * @return When the object was created.
       */
      public long getCreated()
      {
          return created;
      }
  
      /**
       * Returns the expiration time for the object.
       *
       * @return When the object expires.
       */
      public long getExpires()
      {
          return expires;
      }
  
      /**
       * Set the stale status for the object.
       *
       * @param stale Whether the object is stale or not.
       */
      public synchronized void setStale ( boolean stale )
      {
          this.stale = stale;
      }
  
      /**
       * Get the stale status for the object.
       *
       * @return Whether the object is stale or not.
       */
      public synchronized boolean getStale()
      {
          return stale;
      }
  
      /**
       * Is the object stale?
       *
       * @return True if the object is stale.
       */
      public synchronized boolean isStale()
      {
          setStale( (System.currentTimeMillis() - created) > expires );
          return getStale();
      }
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/util/cache/GlobalCache.java
  
  Index: GlobalCache.java
  ===================================================================
  package org.apache.velocity.util.cache;
  
  /*
   * Copyright (c) 1997-2000 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
   *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
   *    "Java Apache Project" must not be used to endorse or promote products
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  // Java Core Classes
  import java.util.Map;
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.Enumeration;
  
  /**
   * This Service functions as a Global Cache.  A global cache is a good
   * place to store items that you may need to access often but don't
   * necessarily need (or want) to fetch from the database everytime.  A
   * good example would be a look up table of States that you store in a
   * database and use throughout your application.  Since information
   * about States doesn't change very often, you could store this
   * information in the Global Cache and decrease the overhead of
   * hitting the database everytime you need State information.
   *
   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
   * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * @version $Id: GlobalCache.java,v 1.1 2000/11/16 01:46:58 jvanzyl Exp $
   */
  public class GlobalCache implements Runnable
  {
      /** The cache. **/
      private Hashtable cache = null;
  
      /** cacheCheckFrequency (default - 5 seconds) */
      private long cacheCheckFrequency = 5000;
          //TurbineResources.getLong("cachedobject.cacheCheckFrequency", 5000);
          
      public static final int EXPIRABLE = 1;
      public static final int REFRESHABLE = 2;
      public static final int PERMANENT = 3;
  
      /**
       * Constructor.
       */
      public GlobalCache()
      {
      }
  
      /**
       * Set the frequency, in thousandths of a seconds,
       * for checking the state of objects in the cache.
       */
      public void setCacheCheckFrequency(long frequency)
      {
          this.cacheCheckFrequency = frequency;
      }
  
      /**
       * Called the first time the Service is used.
       */
      public void init()
      {
          try
          {
              //org.apache.turbine.util.Log.note ("TurbineGlobalCacheService not init()....starting!");
              cache = new Hashtable(20);
  
              // Start housekeeping thread.
              Thread housekeeping = new Thread(this);
              housekeeping.setDaemon(true);
              housekeeping.start();
  
              //setInit(true);
          }
          catch (Exception e)
          {
              //org.apache.turbine.util.Log.error ( "Cannot initialize TurbineGlobalCacheService!" );
              //org.apache.turbine.util.Log.error (e);
          }
      }
  
      /**
       * Returns an item from the cache.
       *
       * @param id The key of the stored object.
       * @return The object from the cache.
       * @exception ObjectExpiredException, when either the object is
       * not in the cache or it has expired.
       */
      //public CachedObject get(String id) throws ObjectExpiredException
      public Object get(String id) //throws ObjectExpiredException
      {
          CachedObject obj = null;
          boolean stale = false;
  
          obj = (CachedObject) cache.get(id);
  
          /*
          if (obj == null)
          {
              // Not in the cache.
              throw new ObjectExpiredException();
          }
          */
  
          /*
          if (obj.isStale())
          {
              // Expired.
              throw new ObjectExpiredException();
          }
          */
  
          if (obj instanceof RefreshableCachedObject)
          {
              // notify it that it's being accessed.
              RefreshableCachedObject rco = (RefreshableCachedObject) obj;
              rco.touch();
          }
  
          return obj.getContents();
      }
  
      /**
       * Adds an object to the cache.
       *
       * @param id The key to store the object by.
       * @param o The object to cache.
       */
      public void put(String id, CachedObject o)
      {
          // If the cache already contains the key, remove it and add
          // the fresh one.
          if ( cache.containsKey(id) )
          {
              cache.remove(id);
          }
          cache.put(id,o);
      }
  
      /**
       * Adds an object to the cache.
       *
       * @param id The key to store the object by.
       * @param o The object to cache.
       */
      public void put(String id, Object o)
      {
          // If the cache already contains the key, remove it and add
          // the fresh one.
          if ( cache.containsKey(id) )
          {
              cache.remove(id);
          }
          cache.put(id,new CachedObject(o));
      }
  
      public boolean contains(String id)
      {
          return cache.containsKey(id);
      }
  
  
      /**
       * Circle through the cache and remove stale objects.  Frequency
       * is determined by the cacheCheckFrequency property.
       */
      public void run()
      {
          while(true)
          {
              // Sleep for amount of time set in cacheCheckFrequency -
              // default = 5 seconds.
              try
              {
                  Thread.sleep(cacheCheckFrequency);
              }
              catch(InterruptedException exc)
              {
              }
  
              clearCache();
          }
      }
  
      /**
       * Iterate through the cache and remove or refresh stale objects.
       */
      public void clearCache()
      {
          Vector refreshThese = new Vector(20);
          // Sync on this object so that other threads do not 
          // change the Hashtable while enumerating over it.      
          synchronized (this)
          {
              for ( Enumeration e = cache.keys(); e.hasMoreElements(); )
              {
                  String key = (String) e.nextElement();
                  CachedObject co = (CachedObject) cache.get(key);
                  if (co instanceof RefreshableCachedObject)
                  {
                      RefreshableCachedObject rco = (RefreshableCachedObject)co;
                      if (rco.isUntouched()) 
                          cache.remove(key);
                      else if (rco.isStale()) 
                          // Do refreshing outside of sync block so as not
                          // to prolong holding the lock on this object
                          refreshThese.addElement(key);
                  }
                  else if ( co.isStale() )
                  {
                      cache.remove(key);
                  }
              }
          }
          
          for ( Enumeration e = refreshThese.elements(); e.hasMoreElements(); )
          {
              String key = (String)e.nextElement();
              CachedObject co = (CachedObject)cache.get(key);
              RefreshableCachedObject rco = (RefreshableCachedObject)co;
              rco.refresh();
          }
      }
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/util/cache/GlobalCacheService.java~
  
  Index: GlobalCacheService.java~
  ===================================================================
  package org.apache.velocity.util.cache;
  
  /*
   * Copyright (c) 1997-2000 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
   *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
   *    "Java Apache Project" must not be used to endorse or promote products
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  // Turbine Stuff
  import org.apache.turbine.services.Service;
  import org.apache.turbine.util.*;
  
  /**
   * GlobalCacheService interface.
   *
   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
   * @version $Id: GlobalCacheService.java~,v 1.1 2000/11/16 01:46:58 jvanzyl Exp $
   */
  public interface GlobalCacheService
      extends Service
  {
      public static final String SERVICE_NAME = "TurbineGlobalCacheService";
  
      /**
       * Gets a cached object given its id (a String).
       *
       * @param id The String id for the object.
       * @return A CachedObject.
       * @exception ObjectExpiredException, if the object has expired in
       * the cache.
       */
      public CachedObject getObject(String id)
          throws ObjectExpiredException;
  
      /**
       * Adds an object to the cache.
       *
       * @param id The String id for the object.
       * @param o The object to add to the cache.
       */
      public void addObject(String id,
                            CachedObject o);
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/util/cache/ObjectExpiredException.java
  
  Index: ObjectExpiredException.java
  ===================================================================
  package org.apache.velocity.util.cache;
  
  /*
   * Copyright (c) 1997-2000 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
   *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
   *    "Java Apache Project" must not be used to endorse or promote products
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  /*
   * Exception thrown when an item either does not exist or has expired
   * from the GlobalCache.
   *
   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
   * @version $Id: ObjectExpiredException.java,v 1.1 2000/11/16 01:46:58 jvanzyl Exp $
   */
  public class ObjectExpiredException
      extends Exception
  {
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/util/cache/Refreshable.java
  
  Index: Refreshable.java
  ===================================================================
  package org.apache.velocity.util.cache;
  
  /*
   * Copyright (c) 1997-2000 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
   *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
   *    "Java Apache Project" must not be used to endorse or promote products
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  // Java stuff.
  import java.util.*;
  
  /**
   * This is the interface for objects you want to refresh themselves
   * from the cache.
   *
   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
   * @version $Id: Refreshable.java,v 1.1 2000/11/16 01:46:58 jvanzyl Exp $
   */
  public interface Refreshable
  {
      /**
       * Refreshes the object.
       */
      public void refresh();
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/util/cache/RefreshableCachedObject.java
  
  Index: RefreshableCachedObject.java
  ===================================================================
  package org.apache.velocity.util.cache;
  
  /*
   * Copyright (c) 1997-2000 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
   *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
   *    "Java Apache Project" must not be used to endorse or promote products
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  // Java stuff.
  import java.util.*;
  
  // Turbine stuff.
  //import org.apache.turbine.services.resources.TurbineResources;
  
  /*
   * The idea of the RefreshableCachedObject is that, rather than
   * removing items from the cache when they become stale, we'll tell them to
   * refresh themselves instead.  That way they'll always be in the
   * cache, and the code to refresh them will be run by the background
   * thread rather than by a user request thread.  You can also set a TTL (Time
   * To Live) for the object.  This way, if the object hasn't been touched
   * for the TTL period, then it will be removed from the cache.
   *
   * This extends CachedObject and provides a method for refreshing the
   * cached object, and resetting its expire time.
   *
   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
   * @version $Id: RefreshableCachedObject.java,v 1.1 2000/11/16 01:46:58 jvanzyl Exp $
   */
  public class RefreshableCachedObject extends CachedObject
      implements Refreshable
  {
  
      /**
       * How long to wait before removing an untouched object from the cache.
       * Negative numbers mean never remove (the default).
       */
      private long timeToLive = -1;
  
      /**
       * The last time the Object was accessed from the cache.
       */
      private long lastAccess;
      
      /**
       * Constructor; sets the object to expire in the default time (30
       * minutes).
       *
       * @param o The object you want to cache.
       */
      public RefreshableCachedObject(Refreshable o)
      {
          super(o);
          lastAccess = System.currentTimeMillis();
      }
  
      /**
       * Constructor.
       *
       * @param o The object to cache.
       * @param expires How long before the object expires, in ms,
       * e.g. 1000 = 1 second.
       */
      public RefreshableCachedObject(Refreshable o,
                                     long expires)
      {
          super(o, expires);
          lastAccess = System.currentTimeMillis();
      }
  
      /** sets the timeToLive member (in milliseconds) */
      public synchronized void setTTL(long l) { timeToLive = l; }
  
      /** gets the timeToLive member (in milliseconds) */
      public synchronized long getTTL() { return timeToLive; }
  
      /**
       * Sets the last acccess time to the current time.
       */
      public synchronized void touch()
      {
          lastAccess = System.currentTimeMillis();
      }
  
      /**
       * Returns true if the object hasn't been touched  
       * in the previous TTL period.
       */
      public synchronized boolean isUntouched()
      {
          if (timeToLive < 0)
              return false;
  
          if (lastAccess + timeToLive < System.currentTimeMillis())
              return true;
          else
              return false;
      }
  
      /**
       * Refresh the object and the created time.
       */
      public void refresh()
      {
          Refreshable r = (Refreshable)getContents();
          synchronized (this)
          {
              r.refresh();
              created = created + getExpires();
          }
      }
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/util/cache/TurbineGlobalCacheService.java~
  
  Index: TurbineGlobalCacheService.java~
  ===================================================================
  package org.apache.velocity.util.cache;
  
  /*
   * Copyright (c) 1997-2000 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine", "Turbine",
   *    "Apache Turbine", "Turbine Project", "Apache Turbine Project" and
   *    "Java Apache Project" must not be used to endorse or promote products
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  // Java Core Classes
  import java.io.*;
  import java.util.*;
  
  // Turbine Utility Classes
  //import org.apache.turbine.util.*;
  //import org.apache.turbine.services.resources.TurbineResources;
  
  // Turbine Services Classes
  //import org.apache.turbine.services.*;
  
  /**
   * This Service functions as a Global Cache.  A global cache is a good
   * place to store items that you may need to access often but don't
   * necessarily need (or want) to fetch from the database everytime.  A
   * good example would be a look up table of States that you store in a
   * database and use throughout your application.  Since information
   * about States doesn't change very often, you could store this
   * information in the Global Cache and decrease the overhead of
   * hitting the database everytime you need State information.
   *
   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
   * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
   * @version $Id: TurbineGlobalCacheService.java~,v 1.1 2000/11/16 01:46:58 jvanzyl Exp $
   */
  public class GlobalCacheService implements Runnable
  {
      /** The cache. **/
      private Hashtable cache = null;
  
      /** cacheCheckFrequency (default - 5 seconds) */
      private long cacheCheckFrequency = 5000;
          //TurbineResources.getLong("cachedobject.cacheCheckFrequency", 5000);
  
      /**
       * Constructor.
       */
      public TurbineGlobalCacheService()
      {
      }
  
      /**
       * Called the first time the Service is used.
       */
      public void init()
      {
          /*
          if ( getInit() )
          {
              return;
          }
          */
  
          try
          {
              //org.apache.turbine.util.Log.note ("TurbineGlobalCacheService not init()....starting!");
              cache = new Hashtable(20);
  
              // Start housekeeping thread.
              Thread housekeeping = new Thread(this);
              housekeeping.setDaemon(true);
              housekeeping.start();
  
              //setInit(true);
          }
          catch (Exception e)
          {
              //org.apache.turbine.util.Log.error ( "Cannot initialize TurbineGlobalCacheService!" );
              //org.apache.turbine.util.Log.error (e);
          }
      }
  
      /**
       * Returns an item from the cache.
       *
       * @param id The key of the stored object.
       * @return The object from the cache.
       * @exception ObjectExpiredException, when either the object is
       * not in the cache or it has expired.
       */
      public CachedObject getObject(String id)
          throws ObjectExpiredException
      {
          CachedObject obj = null;
          boolean stale = false;
  
          obj = (CachedObject) cache.get(id);
  
          if (obj == null)
          {
              // Not in the cache.
              throw new ObjectExpiredException();
          }
  
          if (obj.isStale())
          {
              // Expired.
              throw new ObjectExpiredException();
          }
  
          if (obj instanceof RefreshableCachedObject)
          {
              // notify it that it's being accessed.
              RefreshableCachedObject rco = (RefreshableCachedObject) obj;
              rco.touch();
          }
  
          return obj;
      }
  
      /**
       * Adds an object to the cache.
       *
       * @param id The key to store the object by.
       * @param o The object to cache.
       */
      public void addObject(String id,
                            CachedObject o)
      {
          // If the cache already contains the key, remove it and add
          // the fresh one.
          if ( cache.containsKey(id) )
          {
              cache.remove(id);
          }
          cache.put(id,o);
      }
  
      /**
       * Circle through the cache and remove stale objects.  Frequency
       * is determined by the cacheCheckFrequency property.
       */
      public void run()
      {
          while(true)
          {
              // Sleep for amount of time set in cacheCheckFrequency -
              // default = 5 seconds.
              try
              {
                  Thread.sleep(cacheCheckFrequency);
              }
              catch(InterruptedException exc)
              {
              }
  
              clearCache();
          }
      }
  
      /**
       * Iterate through the cache and remove or refresh stale objects.
       */
      public void clearCache()
      {
          Vector refreshThese = new Vector(20);
          // Sync on this object so that other threads do not 
          // change the Hashtable while enumerating over it.      
          synchronized (this)
          {
              for ( Enumeration e = cache.keys(); e.hasMoreElements(); )
              {
                  String key = (String) e.nextElement();
                  CachedObject co = (CachedObject) cache.get(key);
                  if (co instanceof RefreshableCachedObject)
                  {
                      RefreshableCachedObject rco = (RefreshableCachedObject)co;
                      if (rco.isUntouched()) 
                          cache.remove(key);
                      else if (rco.isStale()) 
                          // Do refreshing outside of sync block so as not
                          // to prolong holding the lock on this object
                          refreshThese.addElement(key);
                  }
                  else if ( co.isStale() )
                  {
                      cache.remove(key);
                  }
              }
          }
          
          for ( Enumeration e = refreshThese.elements(); e.hasMoreElements(); )
          {
              String key = (String)e.nextElement();
              CachedObject co = (CachedObject)cache.get(key);
              RefreshableCachedObject rco = (RefreshableCachedObject)co;
              rco.refresh();
          }
      }
  }