asmuts      02/01/14 22:36:40

  Added:       src/java/org/apache/stratum/jcs/engine/control Cache.java
                        CacheAttributes.java CacheManagerFactory.java
                        CompositeCacheConfigurator.java
                        CompositeCacheManager.java
                        CompositeCacheManagerTester.java
  Log:
  the cache hub, control auxiliaries and memory management plugins
  
  Revision  Changes    Path
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/control/Cache.java
  
  Index: Cache.java
  ===================================================================
  package org.apache.stratum.jcs.engine.control;
  
  import java.io.*;
  import java.util.*;
  
  import org.apache.stratum.jcs.access.*;
  import org.apache.stratum.jcs.access.behavior.*;
  import org.apache.stratum.jcs.access.exception.*;
  import org.apache.stratum.jcs.auxiliary.behavior.*;
  import org.apache.stratum.jcs.auxiliary.disk.*;
  import org.apache.stratum.jcs.engine.*;
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.engine.memory.behavior.*;
  
  // TODO: make configurable
  import org.apache.stratum.jcs.engine.memory.lru.*;
  
  import org.apache.stratum.jcs.engine.control.*;
  import org.apache.stratum.jcs.engine.memory.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  //////////////////////////////////////////////////////
  public class Cache implements ICacheHub, ICache, ICompositeCache, Serializable {
  
    private final static boolean debugcmd = false;//true;
    // removal
    private final static boolean debugR =  true;
  
    public final String className;
  
    // Auxiliary caches.
    private ICache[] auxCaches;
    // track hit counts for each
    private int[] auxHit;
  
    private boolean alive=true;
  
    final String cacheName;
  
    // Region Elemental Attributes
    public Attributes attr;
    // Cache Attributes
    public ICompositeCacheAttributes cacheAttr;
  
    private String source_id = "org.apache.stratum.jcs.engine.control.Cache";
  
    // need to convert to log4j
    final protected Logger log;
  
    // statistics
    private static int numInstances;
    private int ramHit;
    private int miss;
  
    // IMemoryCache
    IMemoryCache memCache;
  
    ///////////////////////////////////////////////////
    public Serializable getSourceId() {
      return this.source_id;
    }
  
    ///////////////////////////////////////////////////////////////////////
    public Cache(String cacheName, ICache[] auxCaches, ICompositeCacheAttributes 
cattr, Attributes attr ) {
  
      numInstances++;
      String s = this.getClass().getName();
      int idx = s.lastIndexOf(".");
      this.className = s.substring(idx+1);
      this.cacheName  = cacheName;
  
      this.auxCaches = auxCaches;
      if (auxCaches != null) {
        this.auxHit = new int[auxCaches.length];
      }
  
      // set from props
      // also need to add cache attributes
      this.attr = attr;
      this.cacheAttr = cattr;
  
      log = LoggerManager.getLogger( this );
  
      if ( debugcmd ) {
        log.setLogLevel( log.DEBUG );
        log.setSystemOut( true );
      }
  
      createMemoryCache( cattr );
  
      if( log.logLevel >= log.DEBUG ) {
        log.debug( "******************* Constructing cache " + cacheName );
      }
      if ( debugcmd ) {
        p( "contructed cache " + cacheName  + " cattr = " + cattr );
      }
  
   }
  
    //////////////////////////////////////////////////////////////////////////////
    public void add( ICacheElement ce )  {
      try {
        memCache.update( ce );
      } catch( Exception e ) {
        log.error( e );
      }
      //memCache.moveToMemory( ce );
      //moveToMemory( (CacheElement)ce );
      return;
    }
  
     /**
      * OSC4j interface put methods, and make it the first in the link list.
      */
    public void put(Serializable key, Serializable val) throws IOException {
      put(key, val, (Attributes)this.attr.copy() );
      return;
    }
    public void put(Serializable key, Serializable val, Attributes attr ) throws 
IOException {
      //p( "puting in cache" );
      // make active after implementing replace
      // to slow to justify this feature
      //if ( this.get( key ) != null ) {
      //  throw new ObjectExistsException( "Object exists for key " + key );
      //}
      if (key == null || val == null) {
        NullPointerException ex = new NullPointerException("key="+key + " and val="+val
            + " must not be null.");
        log.error(ex);
        throw ex;
      }
      try {
        updateCaches(key, val, attr);
      } catch( IOException ioe ) {
        log.error( ioe );
      }
      return;
    }
  
  
  
    ////////////////////////////////////////////
    protected synchronized void updateCaches(Serializable key, Serializable val, 
Attributes attr ) throws IOException {
      CacheElement ce = new CacheElement( cacheName, key, val );
      ce.setAttributes( attr );
      update( ce, true );
    }
  
    ////////////////////////////////////////////
    protected synchronized void updateCaches(Serializable key, Serializable val, 
Attributes attr, boolean updateRemoteCache ) throws IOException {
      CacheElement ce = new CacheElement( cacheName, key, val );
      ce.setAttributes( attr );
      update( ce, updateRemoteCache );
    }
  
    ///////////////////////////////////////////////////////////
    public synchronized void update( ICacheElement ce ) throws IOException {
      update( ce, true );
    }
    ///////////////////////////////////////////////////////////
    public synchronized void update( ICacheElement ce, boolean updateRemoteCache ) 
throws IOException {
  
      if (ce.getKey() instanceof String && 
ce.getKey().toString().endsWith(NAME_COMPONENT_DELIMITER)) {
        throw new IllegalArgumentException(
          "key must not end with " + NAME_COMPONENT_DELIMITER + " for a put 
operation");
      }
  
      if ( log.logLevel >= log.DEBUG ) {
        StringBuffer params = new StringBuffer();
        params.append( "update> key=" + ce.getKey() + ", val=" + ce.getVal() + ", " + 
ce.getAttributes().toString() );
        log.debug( params.toString() );
      }
      if ( debugcmd ) {
        p( "update key = " + ce.getKey() + ", updateRemoteCache = " + 
updateRemoteCache );
      }
  
  
      memCache.update( ce );
  
      // Updates to all auxiliary caches -- remote and laterals, can add as many of 
each
      // as necessary.
      // could put the update criteria in each but it would a bit cumbersome
      // the disk cache would have to check the cache size, the lateral
      // would have to check the region cattr configuration
  
      // UPDATE AUXILLIARY CACHES
      // There are 3 types of auxiliary caches: remote, lateral, and disk
      // more can be added if future auxiliary caches don't fit the model
      // You could run a database cache as either a remote or a local disk.
      // The types would describe the purpose.
      for (int i=0; i < auxCaches.length; i++) {
        ICache aux = auxCaches[i];
  
        if ( debugcmd ) {
          p( "aux.getCacheType() = " + aux.getCacheType() );
        }
  
        // SEND TO REMOTE STORE
        if (aux != null && aux.getCacheType() == ICache.REMOTE_CACHE) {
          if ( log.logLevel >= log.DEBUG ) {
            log.debug( "ce.getAttributes().IS_REMOTE = " + 
ce.getAttributes().IS_REMOTE );
          }
          //if ( first.ce.getAttributes().IS_REMOTE && updateRemoteCache) {
          if ( ce.getAttributes().IS_REMOTE && updateRemoteCache) {
            try {
              // need to make sure the group cache understands that the
              // key is a group attribute on update
              aux.update( ce );
              if ( log.logLevel >= log.DEBUG ) {
                log.debug( "Updated remote store for " + ce.getKey() + ce );
              }
              //p( "Updated remote store for " + ce.getKey() + ce );
            } catch(IOException ex) {
              handleException(ex);
            }
          }
  
        // SEND LATERALLY
        } else
        if ( aux != null && aux.getCacheType() == ICache.LATERAL_CACHE ) {
          // lateral can't do the checking since it is dependent on the cache region
          // restrictions
          if ( debugcmd ) {
            p( "lateralcache in aux list" );
            p( "cattr " + cacheAttr.getUseLateral() );
            p( "attr  " + ce.getAttributes().isSet(Attributes.LATERAL) );
          }
          if ( cacheAttr.getUseLateral() && 
ce.getAttributes().isSet(Attributes.LATERAL) && updateRemoteCache) {
  
            // later if we want a multicast, possibly delete abnormal broadcaster
            // DISTRIBUTE LATERALLY
            // Currently always multicast even if the value is unchanged,
            // just to cause the cache item to move to the front.
            aux.update( ce );
            if ( log.logLevel >= log.DEBUG ) {
              log.debug( "updated lateral cache for " + ce.getKey() );
            }
          }
        // end if lateral
  
        // DISK CACHE
        } else
  
        if (aux != null && aux.getCacheType() == ICache.DISK_CACHE ) {
          // do nothing, the memory manager will call spool where necesary
          // TODO: add option to put all element on disk
        }
  
      } // end for aux list
  
      return;
  
    } // update
  
  
    //////////////////////////////////////////////////////////
    /**
     * ICacheHub method
     */
    public synchronized void spoolToDisk( ICacheElement ce ) {
  
      // SPOOL TO DISK.
      for (int i=0; i < auxCaches.length; i++) {
        ICache aux = auxCaches[i];
  
        if (aux != null && aux.getCacheType() == ICache.DISK_CACHE ) {
          // write the last item to disk.2
          try {
            aux.update( ce );
          } catch(IOException ex) {
            // impossible case.
            ex.printStackTrace();
            throw new IllegalStateException(ex.getMessage());
          }
          catch ( Exception oee ) {
          }
          if( log.logLevel >= log.DEBUG ) {
            log.debug( "moveToMemory -- request to put " +  ce.getKey() + " on disk 
cache[" + i + "]");
          }
        }
      }
  
    } // end spoolToDisk
  
  
  
    /**
      * Gets an item from the cache, and make it the first in the link list.
      */
    /////////////////////////////////////////////////////////
    public Serializable getCacheElement(Serializable key) throws 
ObjectNotFoundException, IOException {
      return get( key, this.LOCAL_INVOKATION );
    } // end get ce
    public Serializable get(Serializable key)  {
      return get( key, false, this.LOCAL_INVOKATION );
    }
    public Serializable get( Serializable key, boolean container )   {
      return get( key, container, this.LOCAL_INVOKATION );
    }
    public Serializable get( Serializable key, boolean container, boolean invocation ) 
{
  
      if ( debugcmd ) {
        p( "in cache get(key,container)" );
      }
  
      //MemoryElementDescriptor me = null;
      ICacheElement ce = null;
      boolean found = false;
  
      try{
  
        if( log.logLevel >= log.DEBUG ) {
          log.debug("get> key="+key);
          log.debug("get> key="+key.toString());
          log.debug("is this a local invocation=" + (invocation == 
this.LOCAL_INVOKATION) );
        }
  
        ce = (ICacheElement)memCache.get( key, true );
  
        if (ce == null) {
          // Item not found in memory.  Try the auxiliary caches if local.
  
  
          for (int i=0; i < auxCaches.length; i++) {
            //Serializable val = null;
            //p( "aux["+i+"]" );
            ICache aux = auxCaches[i];
  
            if ( aux != null ) {
  
              if ( (invocation == this.LOCAL_INVOKATION) || aux.getCacheType() == 
aux.DISK_CACHE ) {
                if ( debugcmd ) {
                  p( "in local block, aux.getCacheType() = " + aux.getCacheType() );
                }
  
                try {
                  //val = aux.get(key);
                  ce = (ICacheElement)aux.get(key, true);
                } catch(IOException ex) {
                  handleException(ex);
                }
              }
  
              if ( debugcmd ) {
                p( "ce = " + ce );
              }
  
              //if (val != null) {
              if (ce != null) {
                found = true;
                // Item found in one of the auxiliary caches.
                auxHit[i]++;
  
                if ( debugcmd ) {
                  p( cacheName + " -- AUX[" + i +"]-HIT for " + key );
                  p( "ce.getKey() = " + ce.getKey() );
                  p( "ce.getVal() = " + ce.getVal() );
                  //p( "ce.getAttributes() = " + ce.getAttributes() );
                }
                if ( log.logLevel >= log.DEBUG ) {
                  log.debug( cacheName + " -- AUX[" + i +"]-HIT for " + key );
                  log.debug( "ce.getKey() = " + ce.getKey() );
                  log.debug( "ce.getVal() = " + ce.getVal() );
                  //log.debug( "ce.getAttributes() = " + ce.getAttributes() );
                }
  
  
                //memCache.moveToMemory( ce );
                memCache.update( ce );
  
                break;
              }
            } // end for
          } // end if invocation = LOCAL
  
        } else {
          found = true;
          ramHit++;
          if ( log.logLevel >= log.DEBUG ) {
            log.debug( cacheName + " -- RAM-HIT for " + key );
          }
        }
  
      } catch( Exception e ) {
        log.error( e );
      }
  
  
      try {
  
        if ( !found ) {
          // Item not found in all caches.
          miss++;
          if ( log.logLevel >= log.DEBUG ) {
            log.debug( cacheName + " -- MISS for " + key );
          }
          return null;
          //throw new ObjectNotFoundException( key + " not found in cache" );
        }
  
      } catch( Exception e ) {
        log.error( e, "Error handling miss" );
        return null;
      }
  
      // HUB Manages expiration
      try {
  
        // Cache item found in memory.
        // The existing logic simply returns null if a cache item is found to be 
expired.
        // Don't we also want to remove it from the cache ?
        if ( !ce.getAttributes().IS_ETERNAL && ( (System.currentTimeMillis() - 
ce.getAttributes().createTime) > (ce.getAttributes().ttl * 1000)) ) {
          // Item expired.
          if ( log.logLevel >= log.INFO ) {
            log.info( ce.getKey() + " expired" );
          }
          if ( debugcmd ) {
            p(  ce.getKey() + " expired" );
          }
          this.remove( key );
          //throw new ObjectNotFoundException( key + " expired from cache" );
          return null;
        }
      } catch( Exception e ) {
        log.error( e, "Error determining expiration period" );
        return null;
      }
  
      if ( container ) {
        return ce;
      } else {
        return ce.getVal();
      }
  
    } // end get
  
  
    /** Lateral removal */
    public void removeLateralDirect(Serializable key) {
      // can't expect a lateral aux cache.  This is a removal tool.
      /**@todo: reimplement in LateralCacheManager */
      //DeleteLateralCacheMulticaster dlcm = new DeleteLateralCacheMulticaster( 
cacheName, (String)key, cacheAttr.getLateralCacheAddrs(), 
cacheAttr.getLateralDeleteServlet()  );
      //dlcm.multicast();
    }
  
  
    /** Removes an item from the cache. */
    public boolean remove(Serializable key) {
      return remove(key, LOCAL_INVOKATION);
    }
  
  
    /**
     *  fromRemote:
     *  If a remove call was made on a cache with both, then the remote
     *  should have been called.  If it wasn't then the remote is down.
     *  we'll assume it is down for all.
     *  If it did come from the remote then the caceh is remotely configured and
     *  lateral removal is unncessary.
     *  If it came laterally then lateral removal is unnecessary.  Does this assumes
     *  that there is only one lateral and remote for the cache?  Not really,
     *  the intial removal should take care of the problem if the source cache was
     *  similiarly configured.  Otherwise the remote cache, if it had no laterals, 
would
     *  remove all the elements from remotely configured caches, but if those caches
     *  had some other wierd laterals that were not remotely configured, only 
laterally propagated
     *  then they would go out of synch.
     *  The same could happen for multiple remotes.
     *  If this looks necessary we will need to build in an identifier to specify the 
source of
     *  a removal.
     */
    // invoked by CacheManager.
    // can't be protected because groupcache method needs to be called from access
    public synchronized boolean remove(Serializable key, boolean nonLocal) {
  
      if( log.logLevel >= log.DEBUG ) {
        log.debug("remove> key="+key+", nonLocal="+nonLocal);
      }
  
  
      //p("remove> key="+key+", nonLocal="+nonLocal);
      boolean removed=false;
  
      try {
        removed = memCache.remove( key );
      } catch ( IOException e ) {
        log.error( e );
      }
  
  
      // Removes from all auxiliary caches.
      for (int i=0; i < auxCaches.length; i++) {
        ICache aux = auxCaches[i];
  
        if (aux == null) {
          continue;
        }
        // avoid notification dead loop.
        int cacheType = aux.getCacheType();
  
        // for now let laterals call remote remove but not vice versa
        if (nonLocal && (cacheType == REMOTE_CACHE || cacheType == LATERAL_CACHE) ) {
          continue;
        }
        try {
          boolean b = aux.remove(key);
          //p( "removed aux.getCacheType() = " + aux.getCacheType() );
          // Don't take the remote removal into account.
          if (!removed && cacheType != REMOTE_CACHE) {
            removed = b;
          }
        } catch(IOException ex) {
          handleException(ex);
        }
      }
      return removed;
  
    } // end remove
  
  
  
    /** Removes all cached items. */
    public synchronized void removeAll() {
  
  
      //map = new HashMap();
      try {
        memCache.removeAll();
      } catch(IOException ex) {
        log.error(ex);
      }
  
      // Removes from all auxiliary disk caches.
      for (int i=0; i < auxCaches.length; i++) {
        ICache aux = auxCaches[i];
  
        if (aux != null && aux.getCacheType() == ICache.DISK_CACHE) {
          try {
            aux.removeAll();
          } catch(IOException ex) {
            handleException(ex);
          }
        }
      }
      return;
    }
  
  
  
    /** Flushes all cache items from memory to auxilliary caches and close the 
auxilliary caches. */
    public void dispose() {
      dispose(LOCAL_INVOKATION);
    }
  
  
    // invoked only by CacheManager.
    protected void dispose(boolean fromRemote) {
      if (!alive)
        return;
      synchronized(this) {
        if (!alive)
          return;
        alive = false;
  
        for (int i=0; i < auxCaches.length; i++) {
          try {
            ICache aux = auxCaches[i];
  
            if (aux == null || fromRemote && aux.getCacheType() == REMOTE_CACHE) {
              continue;
            }
            if (aux.getStatus() == ICache.STATUS_ALIVE) {
  
              if( log.logLevel >= log.DEBUG ) {
                log.debug("size = " + memCache.getSize() );
              }
  
              if ( !(aux.getCacheType() == ICacheType.LATERAL_CACHE && 
!this.cacheAttr.getUseLateral()) ) {
  
                Iterator itr = memCache.getIterator();
  
                while (itr.hasNext()) {
                  Map.Entry entry = (Map.Entry)itr.next();
                  Serializable key = (Serializable)entry.getKey();
                  MemoryElementDescriptor me = 
(MemoryElementDescriptor)entry.getValue();
                  try {
                    if ( aux.getCacheType() == ICacheType.LATERAL_CACHE && 
!me.ce.getAttributes().isSet( Attributes.LATERAL ) ) {
                      continue;
                    }
                    aux.put(key, me.ce.getVal(), me.ce.getAttributes());
                  } catch( Exception e ) {
                    log.error( e );
                  }
                }
              }
              if (aux.getCacheType() == ICache.DISK_CACHE) {
                aux.dispose();
              }
            }
          } catch(IOException ex) {
            handleException(ex);
          }
        }
      }
      p( "Disposed of cache " + cacheName );
      log.warn( "Called close for " + cacheName );
  
    }
  
    //////////////////////////////////////////////////////////////
    /**
     * Though this put is extremely fast, this could bog the
     * cache and should be avoided.
     * The dispose method should call a version of this.
     * Good for testing.
     *
     */
    public void save() {
      if (!alive) {
        return;
      }
      synchronized(this) {
        if (!alive) {
          return;
        }
        alive = false;
  
        for (int i=0; i < auxCaches.length; i++) {
          try {
            ICache aux = auxCaches[i];
  
            if (aux.getStatus() == ICache.STATUS_ALIVE) {
  
              Iterator itr = memCache.getIterator();
  
              while (itr.hasNext()) {
                Map.Entry entry = (Map.Entry)itr.next();
                Serializable key = (Serializable)entry.getKey();
                MemoryElementDescriptor me = (MemoryElementDescriptor)entry.getValue();
                //try {
                  // should call update
                  aux.put(key, me.ce.getVal(), me.ce.getAttributes());
                  // remove this exception from the interface
                //} catch( Exception e ) {
                //  log.error( e );
                //}
              }
            }
          } catch(IOException ex) {
            handleException(ex);
          }
        }
      }
      if( log.logLevel >= log.DEBUG ) {
        log.debug( "Called save for " + cacheName );
      }
    }
  
  
    /////////////////////////////////
    public String getStats(){
      StringBuffer stats = new StringBuffer();
      stats.append("cacheName = " + cacheName + ", numInstances = " + numInstances);
      stats.append("<br> ramSize = " + memCache.getSize() + "/ ramHit = " + ramHit);
  
      for (int i=0; i < auxHit.length; i++) {
        stats.append("/n<br> auxHit[" + i + "] = " + auxHit[i] + ", " + 
this.auxCaches[i].getSourceId() + "");
      }
      stats.append("/n<br> miss = " + miss);
      stats.append("/n<br> cacheAttr = " + cacheAttr.toString() );
      return stats.toString();
    }
  
    /////////////////////////////////
    public int getSize(){
      //return map.size();
      return memCache.getSize();
    }
    public int getCacheType(){
      return COMPOSITE_CACHE;
    }
    public int getStatus(){
      return alive ? STATUS_ALIVE : STATUS_DISPOSED;
    }
    private void handleException(IOException ex) {
      ex.printStackTrace();
    }
  
  
  
    //////////////////////////////////////////////
    public String getCacheName() {
      return cacheName;
    }
  
  
    ////////////////////////////////////////////////
    public Attributes getAttributes() {
      return attr;
    }
  
    ////////////////////////////////////////////////
    public Attributes getElementAttributes( Serializable key ) throws CacheException, 
IOException {
      CacheElement ce = (CacheElement)getCacheElement( key );
      if ( ce == null ) {
        throw new ObjectNotFoundException( "key " + key + " is not found" );
      }
      return ce.getAttributes();
    }
  
  
    //////////////////////////////////////////////////////////////
    /**
     * Create the MemoryCache based on the config parameters.
     * TODO: consider making this an auxiliary, despite its close tie to the
     * CacheHub.
     * TODO: might want to create a memory cache config file separate from
     * that of the hub -- ICompositeCacheAttributes
     *
     */
     private IMemoryCache createMemoryCache( ICompositeCacheAttributes cattr ) {
        // Create memory Cache
        if ( memCache == null ) {
          try {
            Class c = Class.forName( cattr.getMemoryCacheName() );
            this.memCache = (IMemoryCache)c.newInstance();
            this.memCache.initialize( cacheName, cattr, (ICacheHub)this );
          } catch ( Exception e ) {
            log.error( e );
            log.warn( "Using default memory cache" );
            this.memCache = (IMemoryCache)new LRUMemoryCache( cacheName, cattr, 
(ICacheHub)this );
            this.memCache.initialize( cacheName, cattr, (ICacheHub)this );
          }
        } else {
          log.warn( "Trying to create a memory cache after it already exists." );
        }
        return memCache;
     } // end createMemoryCache
  
  //  ////////////////////////////////////
  //  public void dumpMap() {
  //    memCache.dumpMap();
  //  }
  //  //////////////////////////////////////
  //  public void dumpCacheEntries() {
  //    memCache.dumpCacheEntries();
  //  }
  
    ///////////////////////////////////////////////
    public static void p( String s ) {
      System.out.println( "Cache: " + s );
    }
  
  }
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/control/CacheAttributes.java
  
  Index: CacheAttributes.java
  ===================================================================
  package org.apache.stratum.jcs.engine.control;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  import org.apache.stratum.jcs.engine.behavior.*;
  
  
  /** Most of this class should be deprecated.
   *  TODO: remove or deprecate unused methods.
   *  org.apache.stratum.jcs.engine.CompositeCacheAttributes
   *  is used instead.  This class should probably be removed and the other repackaged.
   */
  public class CacheAttributes implements ICacheAttributes, Serializable {
  
    private String cacheName;
  
    // need to keep a cetral configuration
    // so regions can be created programmaticall rather than only
    // during initalization
    private ArrayList lateralCacheAddrs = new ArrayList();
    private String lateralDeleteServlet;
    private String lateralReceiveServlet;
  
    // remove, unnecessary
    private boolean isLocal     = false;
    // remove
    private boolean dist        = false;
  
    private boolean useLateral  = false;
    private boolean useRemote   = false;
    private boolean useDisk     = true;
  
    private int maxObjs  = 100;
    private int maxBytes = 100000;
  
    // not used by the current disk cache
    private int diskSize = 1000000;
    private int cleanInterval = 1;
  
    private String diskPath = "c:/";
  
    // should use an array of the cache types or the particular
    // instances, this is too inflexible
    private String accessSeq = "disk,remote";
  
  
    private String remoteServiceName = "";
    private String remoteHost = "localhost";
    private int remotePort = 1101;
  
    // not used yet
    private String secondaryRemoteHost = "localhost";
    private int secondaryRemotePort = 1102;
  
    ////////////////////////////////////
    public CacheAttributes() { }
  
    ////////////////////////////////////
    public void setIsLocal( boolean isLocal ) {
      this.isLocal = isLocal;
    }
  
    ////////////////////////////////////
    public boolean getIsLocal( ) {
      return isLocal;
    }
  
    ////////////////////////////////////
    public void setMaxObjects( int maxObjs ) {
      this.maxObjs = maxObjs;
    }
  
    ////////////////////////////////////
    public int getMaxObjects( ) {
      return this.maxObjs;
    }
  
    ////////////////////////////////////
    public void setMaxBytes( int maxBytes ) {
      this.maxBytes = maxBytes;
    }
  
    /////////////////////////////////////
    public int getMaxBytes( ) {
      return this.maxBytes;
    }
  
  
    ////////////////////////////////////
    public void setUseDisk( boolean useDisk ) {
      this.useDisk = useDisk;
    }
  
    ////////////////////////////////////
    public boolean getUseDisk( ) {
      return useDisk;
    }
  
    ////////////////////////////////////////
    // REMOVE THESE
    public void setDist( boolean dist ) {
      this.dist = dist;
    }
    public boolean getDist( ) {
      return this.dist;
    }
  
    ///////////////////////////////////////////////////
    public void setUseLateral( boolean b ) {
      this.useLateral = b;
    }
    public boolean getUseLateral( ) {
      return this.useLateral;
    }
  
  
    ////////////////////////////////////////
    public void setAccessSeq( String seq ) {
      this.accessSeq = seq;
    }
  
    ////////////////////////////////////////
    public String getAccessSeq( ) {
      return this.accessSeq;
    }
  
  
    ////////////////////////////////////////
    public void setCacheName( String s ) {
      this.cacheName = s;
    }
    public String getCacheName( ) {
      return this.cacheName;
    }
  
    ////////////////////////////////////////
    public void setRemoteServiceName( String s ) {
      this.remoteServiceName = s;
    }
    public String getRemoteServiceName( ) {
      return this.remoteServiceName;
    }
  
  
    ////////////////////////////////////
    public void setDiskCacheSize( int size ) {
      this.diskSize = size;
    }
  
    ////////////////////////////////////
    public void setDiskPath( String path ) {
      this.diskPath = path;
    }
  
    ////////////////////////////////////
    public String getDiskPath( ) {
      return this.diskPath;
    }
  
    ////////////////////////////////////
    public void setCleanInterval( int seconds ) {
      this.cleanInterval = seconds;
    }
  
    ////////////////////////////////////
    public void addLateralCacheAddr( String ipAddr, int port) {
      this.lateralCacheAddrs.add( ipAddr + ":" + port );
    }
  
    ////////////////////////////////////////////////
    public void setLateralCacheAddrs( ArrayList addrs ) {
      this.lateralCacheAddrs = addrs;
    }
    public ArrayList getLateralCacheAddrs() {
      return this.lateralCacheAddrs;
    }
  
    ////////////////////////////////////
    public void setLateralDeleteServlet( String name ) {
      this.lateralDeleteServlet = name;
    }
    public String getLateralDeleteServlet() {
      return lateralDeleteServlet;
    }
  
    ////////////////////////////////////
    public void setLateralReceiveServlet( String name ) {
      this.lateralReceiveServlet = name;
    }
    public String getLateralReceiveServlet() {
      return lateralReceiveServlet;
    }
  
  
    ////////////////////////////////////
    public void setUseRemote( boolean useRemote ) {
      this.useRemote = useRemote;
    }
  
    ////////////////////////////////////
    public boolean getUseRemote( ) {
      return this.useRemote;
    }
  
    ////////////////////////////////////
    public void setRemoteHost( String host ) {
      this.remoteHost = host;
    }
  
    ////////////////////////////////////
    public String getRemoteHost( ) {
      return this.remoteHost;
    }
  
    ////////////////////////////////////
    public void setRemotePort( int port ) {
      this.remotePort = port;
    }
  
    ////////////////////////////////////
    public int getRemotePort( ) {
      return this.remotePort;
    }
  
  
    // add the secondary remote configuration information
    // TO BE IMPLEMENTED
  
    ////////////////////////////////////
    public void setSecondaryRemoteHost( String host ) {
      this.secondaryRemoteHost = host;
    }
  
    ////////////////////////////////////
    public String getSecondaryRemoteHost( ) {
      return this.secondaryRemoteHost;
    }
  
    ////////////////////////////////////
    public void setSecondaryRemotePort( int port ) {
      this.secondaryRemotePort = port;
    }
  
    ////////////////////////////////////
    public int getSecondaryRemotePort( ) {
      return this.secondaryRemotePort;
    }
  
    /////////////////////////////////////////
    public String toString() {
      StringBuffer info = new StringBuffer();
      info.append( "\n" );
      info.append( "lateralCacheAddrs = " + lateralCacheAddrs +  "\n" );
      info.append( "lateralDeleteServlet = " + lateralDeleteServlet +  "\n" );
      info.append( "lateralReceiveServlet = " + lateralReceiveServlet +  "\n" );
      info.append(  "isLocal = " + isLocal + "\n" );
      info.append(  "useLateral = " + useLateral   + "\n" );
      info.append(  "useRemote = " + useRemote + "\n" );
      info.append(  "useDisk = " + useDisk   + "\n" );
      info.append( "maxObjs = " + maxObjs + "\n" );
      info.append( " = " + maxBytes + "\n" );
      info.append( " = " + diskSize + "\n" );
      info.append( " = " + cleanInterval + "\n" );
      info.append( "diskPath = " + diskPath + "\n" );
      info.append( "accessSeq = " + accessSeq + "\n" );
      info.append( "remoteHost = " + remoteHost + "\n" );
      info.append( "remotePort = " + remotePort + "\n" );
      info.append( "secondaryRemoteHost = " + secondaryRemoteHost + "\n" );
      info.append( "secondaryRemotePort = " + secondaryRemotePort + "\n" );
      return info.toString();
    }
  
  
    ///////////////////////////////////////////////////
    public ICacheAttributes copy () {
      try {
        return (CacheAttributes)this.clone();
      } catch( Exception e ) {
        return new CacheAttributes();
      }
    }
  
  }
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/control/CacheManagerFactory.java
  
  Index: CacheManagerFactory.java
  ===================================================================
  package org.apache.stratum.jcs.engine.control;
  
  import java.io.*;
  import java.rmi.*;
  import java.rmi.registry.*;
  import java.rmi.server.*;
  import java.util.*;
  import java.sql.*;
  
  import org.apache.stratum.jcs.access.*;
  import org.apache.stratum.jcs.engine.control.*;
  import org.apache.stratum.jcs.engine.*;
  import org.apache.stratum.jcs.auxiliary.disk.*;
  import org.apache.stratum.jcs.auxiliary.remote.*;
  
  // UTILS
  import org.apache.stratum.jcs.utils.log.*;
  
  
  /////////////////////////////////////////////////////////////
  public class CacheManagerFactory {
    private static CompositeCacheManager instance;
  
    protected static boolean debug = true;
    private static boolean debugR = false;
    protected static boolean cmd = false;
  
    ///////////////////////////////////////////////////////////
    private CacheManagerFactory() {
    }
  
     ///////////////////////////////////////////////////////////////////
     public static CompositeCacheManager getInstance() { //throws IOException, 
NotBoundException {
      return getInstance(null);
     }
     ///////////////////////////////////////////////////////////////////////////
     public static CompositeCacheManager getInstance(String propFile) //throws 
IOException, NotBoundException
     {
        if (instance == null) {
          synchronized(CompositeCacheManager.class) {
            if (instance == null) {
              p1( "instance is null" );
              instance = propFile == null ? new CompositeCacheManager() : new 
CompositeCacheManager(propFile);
            }
          }
        }
        if ( debug ) {
          instance.log.logIt( "Manager stats : " + instance.getStats() + "<br> -- in 
getInstance()" );
  
          if ( cmd ) {
            System.out.println( "Manager stats : " + instance.getStats() + "<br> -- in 
getInstance()" );
          }
        }
        instance.incrementClients();
        return instance;
     }
  
    //////////////////////////////////////
    private void p(String s) {
      //System.out.println( "CacheManagerFactory: " + s + " 
>"+Thread.currentThread().getName() );
      instance.log.debug( "CacheManagerFactory: " + s + " 
>"+Thread.currentThread().getName() );
    }
  
    //////////////////////////////////////
    private static void p1(String s) {
      System.out.println( "CacheManagerFactory: " + s );
    }
  
    ///////////////////////////////////////
    public void finalize() {
      p1( "THE ARE KILLING ME" );
    }
  
  } // end class
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/control/CompositeCacheConfigurator.java
  
  Index: CompositeCacheConfigurator.java
  ===================================================================
  package org.apache.stratum.jcs.engine.control;
  
  import org.apache.stratum.jcs.config.*;
  import java.util.*;
  import java.io.*;
  
  //import org.apache.stratum.jcs.auxiliary.*;
  import org.apache.stratum.jcs.auxiliary.behavior.*;
  import org.apache.stratum.jcs.config.*;
  import org.apache.stratum.jcs.engine.*;
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.auxiliary.lateral.*;
  import org.apache.stratum.jcs.auxiliary.lateral.behavior.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  /**
   * This class is based on the log4j class org.apache.log4j.PropertyConfigurator
   * which was made by:
   *  "Luke Blanshard" <[EMAIL PROTECTED]>
   *  "Mark DONSZELMANN" <[EMAIL PROTECTED]>
   *  "Anders Kristensen" <[EMAIL PROTECTED]>
   */
  //////////////////////////////////////////////////
  public class CompositeCacheConfigurator {
  
    // development level debug we want remove by the compiler for production
    static final boolean debug = false; //true;
  
    static final String DEFAULT_REGION = "jcs.default";
    static final String REGION_PREFIX = "jcs.region.";
    static final String SYSTEM_REGION_PREFIX = "jcs.system.";
    static final String AUXILIARY_PREFIX = "jcs.auxiliary.";
    static final String ATTRIBUTE_PREFIX = ".attributes";
    static final String CACHE_ATTRIBUTE_PREFIX = ".cacheattributes";
    static final String ELEMENT_ATTRIBUTE_PREFIX = ".elementattributes";
  
    private static Logger log = LoggerManager.getLogger( 
CompositeCacheConfigurator.class );
  
    private CompositeCacheManager ccMgr;
  
    //////////////////////////////////////////////////////////////
    public CompositeCacheConfigurator( CompositeCacheManager ccMgr ) {
      this.ccMgr = ccMgr;
    }
  
     //////////////////////////////////////////////////////////////////////
    /**
     *  Configure cached for file name.
     */
    public void doConfigure(String configFileName) {
      Properties props = new Properties();
      try {
        FileInputStream istream = new FileInputStream(configFileName);
        props.load(istream);
        istream.close();
      }
      catch (IOException e) {
        log.error(e, "Could not read configuration file ["+configFileName+"].");
        log.error("Ignoring configuration file [" + configFileName+"].");
        return;
      }
      // If we reach here, then the config file is alright.
      doConfigure(props);
    }
  
    ////////////////////////////////////////////////////////////////////
    /** Configure cache for properties object */
    public void doConfigure(Properties properties) {
  
      // store props for use by non configured caches
      ccMgr.props = properties;
      // set default value list
      setDefaultAuxValues( properties );
      // set default attr
      setDefaultCompositeCacheAttributes(properties);
  
      // set up ssytem caches to be used by non system caches
      // need to make sure there is no circuarity of reference
      parseSystemRegions( properties );
  
      // setup preconfigured caches
      parseRegions( properties );
  
    } // end doConfigure
  
    /////////////////////////////////////////////////
    /**
     *  Set the default aux list for new caches.
     */
    protected void setDefaultAuxValues(Properties props) {
      String value =  OptionConverter.findAndSubst(DEFAULT_REGION, props);
      ccMgr.defaultAuxValues = value;
      if ( debug ) {
        p( "setting defaults to " + value );
      }
      log.info( "setting defaults to " + value );
    }
  
      /////////////////////////////////////////////////
    /**
     *  Set the default CompositeCacheAttributes new caches.
     */
    protected void setDefaultCompositeCacheAttributes(Properties props) {
  
      ICompositeCacheAttributes icca = parseCompositeCacheAttributes(props, "", 
this.DEFAULT_REGION );
      ccMgr.setDefaultCacheAttributes( icca );
      if ( debug ) {
        p( "setting defaultCompositeCacheAttributes to " + icca );
      }
      log.info( "setting defaultCompositeCacheAttributes to " + icca );
    }
  
    ////////////////////////////////////////////////////////
    /**
     *  Create caches used internally.  System status gives them creation priority.
     */
    protected void parseSystemRegions(Properties props) {
      Enumeration enum = props.propertyNames();
      while(enum.hasMoreElements()) {
        String key = (String) enum.nextElement();
        if(key.startsWith(SYSTEM_REGION_PREFIX) && (key.indexOf("attributes") == -1)) {
              String regionName = key.substring(SYSTEM_REGION_PREFIX.length());
              String value =  OptionConverter.findAndSubst(key, props);
          ICache cache;
              synchronized(regionName) {
                cache = parseRegion(props, regionName, value, null, 
SYSTEM_REGION_PREFIX);
              }
          ccMgr.systemCaches.put(regionName, cache);
          // to be availiable for remote reference they need to be here as well
          ccMgr.caches.put(regionName, cache);
        }
      }
    }
  
  
    ////////////////////////////////////////////////////////
    /**
     *  Parse region elements.
     */
    protected void parseRegions(Properties props) {
      Enumeration enum = props.propertyNames();
      while(enum.hasMoreElements()) {
        String key = (String) enum.nextElement();
        if(key.startsWith(REGION_PREFIX) && (key.indexOf("attributes") == -1)) {
              String regionName = key.substring(REGION_PREFIX.length());
              String value =  OptionConverter.findAndSubst(key, props);
          ICache cache;
              synchronized(regionName) {
                cache = parseRegion(props, regionName, value);
              }
          ccMgr.caches.put(regionName, cache);
        }
      }
    }
  
  
    ///////////////////////////////////////////////////////////////////
    /**
     * Create cache region.
     */
    protected ICache parseRegion(Properties props, String regName, String value) {
      return parseRegion( props, regName, value, null, REGION_PREFIX );
    }
    protected ICache parseRegion(Properties props, String regName, String value, 
ICompositeCacheAttributes cca) {
      return parseRegion( props, regName, value, cca, REGION_PREFIX );
    }
    protected ICache parseRegion(Properties props, String regName, String value, 
ICompositeCacheAttributes cca, String regionPrefix) {
  
      List auxList = new ArrayList();
  
      log.debug("Parsing for [" +regName +"] with value=[" + value+"].");
      // We must skip over ',' but not white space
      StringTokenizer st = new StringTokenizer(value, ",");
  
      // If value is not in the form ", appender.." or "", then we should set
      // the priority of the category.
  
      if(!(value.startsWith(",") || value.equals(""))) {
        // just to be on the safe side...
        if(!st.hasMoreTokens()) {
              return null;
        }
      }
  
      ICache auxCache;
      String auxName;
      while(st.hasMoreTokens()) {
        auxName = st.nextToken().trim();
        if(auxName == null || auxName.equals(",")) {
              continue;
        }
        log.debug("Parsing auxiliary named \"" + auxName +"\".");
  
        auxCache = parseAuxiliary(props, auxName, regName );
        if(auxCache != null) {
              auxList.add(auxCache);
        }
      }
  
      ICache[] auxCaches = (ICache[])auxList.toArray(new ICache[0]);
  
      // GET COMPOSITECACHEATTRIBUTES
      if ( cca == null ) {
        cca = parseCompositeCacheAttributes( props, regName, regionPrefix );
      }
  
      ICache cache = null;
      if ( regionPrefix.equals( SYSTEM_REGION_PREFIX ) ) {
        cache = ccMgr.createSystemCache(regName, auxCaches, cca, new Attributes() );
      } else {
        cache = ccMgr.createCache(regName, auxCaches, cca, new Attributes() );
      }
      return cache;
  
    } // parseRegion
  
  
  
    /**
     *  Get an compositecacheattributes for the listed region.
     */
    protected ICompositeCacheAttributes parseCompositeCacheAttributes(Properties 
props, String regName) {
      return parseCompositeCacheAttributes(props, regName, REGION_PREFIX);
    }
    protected ICompositeCacheAttributes parseCompositeCacheAttributes(Properties 
props, String regName, String regionPrefix) {
  
        // GET ATTRIBUTES
      ICompositeCacheAttributes ccAttr;
  
      String attrName = regionPrefix + regName + CACHE_ATTRIBUTE_PREFIX;
  
      // auxFactory was not previously initialized.
      //String prefix = regionPrefix + regName + ATTRIBUTE_PREFIX;
      ccAttr = (ICompositeCacheAttributes) OptionConverter.instantiateByKey(props, 
attrName,
                org.apache.stratum.jcs.engine.behavior.ICompositeCacheAttributes.class,
                null);
      if(ccAttr == null) {
        log.warn("Could not instantiate ccAttr named \"" + attrName + "\".  Using 
defaults.");
        ICompositeCacheAttributes ccAttr2 = ccMgr.getDefaultCacheAttributes();
        ccAttr = ccAttr2.copy();
      }
  
      log.debug("Parsing options for \"" + attrName +"\".");
      PropertySetter.setProperties(ccAttr, props, attrName + ".");
      ccAttr.setCacheName( regName );
      if ( debug ) {
        p( "ccAttr = " + ccAttr.toString() );
      }
      log.debug("End of parsing for \"" + attrName +"\".");
  
  
      // GET CACHE FROM FACTORY WITH ATTRIBUTES
      ccAttr.setCacheName(regName);
      return ccAttr;
  
    } // end parCacheAttribute
  
  
    /**
     *  Get an aux cache for the listed aux for a region.
     */
    protected ICache parseAuxiliary(Properties props, String auxName, String regName) {
      ICache auxCache;
  
      // GET FACTORY
      IAuxiliaryCacheFactory auxFac = ccMgr.registryFacGet(auxName);
      if( auxFac == null ) {
        // auxFactory was not previously initialized.
        String prefix = AUXILIARY_PREFIX + auxName;
        auxFac = (IAuxiliaryCacheFactory) OptionConverter.instantiateByKey(props, 
prefix,
                                              
org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheFactory.class,
                                              null);
        if(auxFac == null) {
          log.error("Could not instantiate auxFactory named \"" + auxName + "\".");
          return null;
        }
        auxFac.setName(auxName);
        ccMgr.registryFacPut(auxFac);
      }
  
  
      // GET ATTRIBUTES
      IAuxiliaryCacheAttributes auxAttr = ccMgr.registryAttrGet(auxName);
      String attrName = AUXILIARY_PREFIX + auxName + ATTRIBUTE_PREFIX;
      if( auxAttr == null ) {
        // auxFactory was not previously initialized.
        String prefix = AUXILIARY_PREFIX + auxName + ATTRIBUTE_PREFIX;
        auxAttr = (IAuxiliaryCacheAttributes) OptionConverter.instantiateByKey(props, 
prefix,
                                              
org.apache.stratum.jcs.auxiliary.behavior.IAuxiliaryCacheAttributes.class,
                                              null);
        if(auxFac == null) {
          log.error("Could not instantiate auxAttr named \"" + attrName + "\".");
          return null;
        }
        auxAttr.setName(auxName);
        ccMgr.registryAttrPut(auxAttr);
      }
  
      auxAttr = auxAttr.copy();
  
      log.debug("Parsing options for \"" + attrName +"\".");
      PropertySetter.setProperties(auxAttr, props, attrName + ".");
      auxAttr.setCacheName( regName );
      if ( debug ) {
        p( "auxAttr = " + auxAttr.toString() );
      }
      log.debug("End of parsing for \"" + attrName +"\".");
  
  
      // GET CACHE FROM FACTORY WITH ATTRIBUTES
      auxAttr.setCacheName( regName );
      auxCache = auxFac.createCache( auxAttr );
      return auxCache;
  
    } // end parseregion
  
  
    ///////////////////////////////////////////////////////
    private void p( String s ) {
      System.out.println( "CompositeCacheConfigurator: " + s );
    }
  
  }  // end
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/control/CompositeCacheManager.java
  
  Index: CompositeCacheManager.java
  ===================================================================
  package org.apache.stratum.jcs.engine.control;
  
  //////////////////////////////////
  import  java.io.*;
  import  java.rmi.*;
  import  java.rmi.registry.*;
  import  java.rmi.server.*;
  import  java.util.*;
  import  java.sql.*;
  
  /////////////////////////////////////
  //import org.apache.stratum.jcs.auxiliary.*;
  import org.apache.stratum.jcs.auxiliary.behavior.*;
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.engine.control.*;
  import org.apache.stratum.jcs.engine.*;
  import org.apache.stratum.jcs.access.*;
  import org.apache.stratum.jcs.engine.control.Cache;
  import org.apache.stratum.jcs.auxiliary.disk.*;
  import org.apache.stratum.jcs.auxiliary.lateral.*;
  import org.apache.stratum.jcs.auxiliary.remote.*;
  import org.apache.stratum.jcs.auxiliary.remote.behavior.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  ///////////////////////////////////////////////////////////////////////
  public class CompositeCacheManager implements ICompositeCacheManager, 
IRemoteCacheConstants, Serializable {
  //IRemoteCacheListener, IRemoteCacheConstants, Serializable {
  
    protected Hashtable caches = new Hashtable();
    protected Hashtable systemCaches = new Hashtable();
  
    public final Logger log;
    private int clients;
  
    protected ICompositeCacheAttributes defaultCacheAttr = new 
CompositeCacheAttributes();
    protected Attributes defaultElementAttr = new Attributes();
  
    // Defaults the cache service name to the rmi server's class name.
    private String remoteServiceName;
  
   /**
    *  Used internally to keep track of configured auxiliaries.
    */
    protected Hashtable auxFacs = new Hashtable(11);
    protected Hashtable auxAttrs = new Hashtable(11);
  
    protected Properties props;
  
    // the deafult auxiliary caches to be used by the non preconfigured
    protected String defaultAuxValues;
  
    protected static boolean debug = false;
    protected static boolean debugCnst = false;
    private static boolean debugR = false;
    protected static boolean cmd = false;
    private static final boolean pOut = false; //true;
  
    ////////////////////////////////////////////////
    protected CompositeCacheManager () {
      this("/cache.ccf");
      if ( debugCnst ) {
        p( "creating cache manager with default propsfile" );
      }
    }
  
  
    /////////////////////////////////////////////////
    protected CompositeCacheManager( String propFile ) {
      if ( cmd ) {
        p( "creating cache manager with propFile = " + propFile );
      }
      log = LoggerManager.getLogger(this);
  
      Properties props = new Properties();
      InputStream is = getClass().getResourceAsStream(propFile);
      try {
        props.load(is);
        if (debug) {
          log.debug("props.size=" + props.size() + ", " + props);
        }
      } catch (IOException ex) {
        log.error(ex);
        throw  new IllegalStateException(ex.getMessage());
      } finally {
        try {
          is.close();
        } catch (IOException ignore) {}
      }
  
      // need to do something for defaults
      // create a default entry in the propsfile
      //setDefaults( props );
  
      // Create caches.
      try {
        createCaches(props);
      } catch (IOException ex) {
        log.error(ex);
        throw  new IllegalStateException(ex.getMessage());
      } catch (NotBoundException ex) {
        log.error(ex);
        throw  new IllegalStateException(ex.getMessage());
      }
  
    }
  
  
    /////////////////////////////////////////////
    public ICompositeCacheAttributes getDefaultCacheAttributes() {
      return this.defaultCacheAttr.copy();
    }
    public void setDefaultCacheAttributes( ICompositeCacheAttributes icca ) {
      this.defaultCacheAttr = icca;
    }
  
    /////////////////////////////////////////////////////////////
    private void createCaches (Properties props) throws IOException, NotBoundException 
{
      CompositeCacheConfigurator ccc = new CompositeCacheConfigurator( this );
      ccc.doConfigure( props );
    } // end createCaches
  
  
    /** method for internal system cache creation */
    protected Cache createSystemCache (String cacheName, ICache[] auxCaches, 
ICompositeCacheAttributes cattr, Attributes attr ) {
      if ( cmd ) {
        p( "called create cache in cachemanager" );
      }
      return new Cache( cacheName, auxCaches, cattr, attr );
    }
    /**
     * Factory method to create the actual Cache instance.
     * Subclass can override this method to create the specific cache.
     */
    protected Cache createCache (String cacheName, ICache[] auxCaches, 
ICompositeCacheAttributes cattr, Attributes attr ) {
      if ( cmd ) {
        p( "called create cache in cachemanager" );
      }
      return new Cache( cacheName, auxCaches, cattr, attr );
    }
  
  
    /////////////////////////////////////////////////////////////
    private ICache[] getAuxCaches( String cacheName, IAuxiliaryCacheAttributes iaca ) {
  
      List auxList = new ArrayList();
  
      Enumeration enum = auxFacs.elements();
      while( enum.hasMoreElements() ) {
        IAuxiliaryCacheFactory iacf = (IAuxiliaryCacheFactory)enum.nextElement();
        // need default ilca here.
        ICache cache = iacf.createCache( iaca );
        auxList.add(cache);
      }
  
      return  (ICache[])auxList.toArray(new ICache[0]);
  
    } // end getAucCaches
  
  
    /////////////////////////////////////////////////////////
    public ICache getCache (String cacheName) {
      return  getCache(cacheName, this.defaultCacheAttr.copy() );
    }
    /////////////////////////////////////////////////////////
    public ICache getCache (String cacheName, ICompositeCacheAttributes cattr ) {
      cattr.setCacheName( cacheName );
      return  getCache( cattr, this.defaultElementAttr );
    }
    public ICache getCache (String cacheName, ICompositeCacheAttributes cattr, 
Attributes attr ) {
      cattr.setCacheName( cacheName );
      return  getCache( cattr, this.defaultElementAttr );
    }
    public ICache getCache ( ICompositeCacheAttributes cattr ) {
      return  getCache( cattr, this.defaultElementAttr );
    }
    /////////////////////////////////////////////////////////
    /** If the cache is created the CacheAttributes and the element Attributes will
     *  be ignored.  Currently there is no overiding once it is set up.
     *  Overriding hte default elemental atributes will require cahnging the way the
     *  atributes are assigned to elements.
     *  Get cache creates a cache with defaults if none are specified.
     *  We might want to create separate method for creating/getting. . .
     */
    public ICache getCache (ICompositeCacheAttributes cattr, Attributes attr ) {
  
      if (debug) {
        p("cattr = " + cattr );
      }
  
      ICache cache = (ICache)caches.get(cattr.getCacheName());
      if (cache == null) {
        synchronized (caches) {
          cache = (ICache)caches.get(cattr.getCacheName());
          if (cache == null) {
            cattr.setCacheName( cattr.getCacheName() );
            //ICache[] auxCaches = getAuxCaches(cattr.getCacheName(), cattr );
            // need to call parse region of ccc
            //cache = createCache(cattr.getCacheName(), auxCaches, cattr, attr );
            CompositeCacheConfigurator ccc = new CompositeCacheConfigurator( this );
            cache = ccc.parseRegion( this.props, cattr.getCacheName(), 
this.defaultAuxValues, cattr );
            caches.put(cattr.getCacheName(), cache);
          }
        }
      }
      if (debug) {
        p("Manager stats : " + getStats());
      }
      return  cache;
    }
  
  
    ////////////////////////////////////////////////////////////////
    public void freeCache (String name) {
      freeCache(name, Cache.LOCAL_INVOKATION);
    }
  
  
    //////////////////////////////////////////////////////////////
    public void freeCache (String name, boolean fromRemote) {
      Cache cache = (Cache)caches.get(name);
      if (cache != null) {
        cache.dispose(fromRemote);
      }
    }             // end freeCache
  
    //////////////////////////////////////////////////////////
    public String getStats () {
      StringBuffer stats = new StringBuffer();
      Enumeration allCaches = caches.elements();
      while (allCaches.hasMoreElements()) {
        ICache cache = (ICache)allCaches.nextElement();
        if (cache != null) {
          stats.append("<br>&nbsp;&nbsp;&nbsp;" + cache.getStats() + " clients = "
              + clients);
        }
      }
      return  stats.toString();
    }  // end getStats
  
  
    //////////////////////////////////////////////
    protected void incrementClients () {
      clients++;
    }
  
    /** Disposes of all caches. */
    public void release () {
      release(Cache.LOCAL_INVOKATION);
    }
    /////////////////////////////////////////////////
    private void release (boolean fromRemote) {
      synchronized (CompositeCacheManager.class) {
        // Wait until called by the last client
        if (--clients > 0) {
          p( "release was called; clients = " + clients );
          log.warn("clients = " + clients);
          return;
        }
        log.warn("clients = " + clients);
        log.warn("There are " + caches.size() + " caches open");
        log.warn("DISPOSING OF ALL CACHES");
        log.warn( getStats() );
        p( "DISPOSING OF ALL CACHES" );
        p( getStats() );
  
        Enumeration allCaches = caches.elements();
        while (allCaches.hasMoreElements()) {
          Cache cache = (Cache)allCaches.nextElement();
          if (cache != null) {
            cache.dispose(fromRemote);
          }
        }
      }
      log.flush();
    }             //end release()
  
    //////////////////////////////////////////////////////////
    /** Returns a list of the current cache names. */
    public String[] getCacheNames () {
      String[] list = new String[caches.size()];
      int i = 0;
      for (Iterator itr = caches.keySet().iterator(); itr.hasNext();) {
        list[i++] = (String)itr.next();
      }
      return  list;
    }
  
  
    ///////////////////////////////////////
    public int getCacheType() {
      return COMPOSITE_CACHE;
    }
  
    ////////////////////////////////////////
    public ICompositeCacheAttributes getDefaultCattr() {
      return this.defaultCacheAttr;
    }
  
     //////////////////////////////////////////
    void registryFacPut(IAuxiliaryCacheFactory auxFac) {
      auxFacs.put(auxFac.getName(), auxFac);
    }
    IAuxiliaryCacheFactory registryFacGet(String name) {
      return (IAuxiliaryCacheFactory)auxFacs.get(name);
    }
  
    //////////////////////////////////////////
    void registryAttrPut(IAuxiliaryCacheAttributes auxAttr) {
      auxAttrs.put(auxAttr.getName(), auxAttr);
    }
    IAuxiliaryCacheAttributes registryAttrGet(String name) {
      return (IAuxiliaryCacheAttributes)auxAttrs.get(name);
    }
  
    /////////////////////////////////////////////
    public void p( String s ) {
      if ( log.logLevel >= log.DEBUG ) {
        log.debug( s );
      }
      if ( pOut ) {
        System.out.println( "CompositeCacheManager: " + s );
      }
    }
  
  }  // end class
  
  
  
  
  
  
  1.1                  
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/engine/control/CompositeCacheManagerTester.java
  
  Index: CompositeCacheManagerTester.java
  ===================================================================
  package org.apache.stratum.jcs.engine.control;
  
  //////////////////////////////////
  import  java.io.*;
  import  java.rmi.*;
  import  java.rmi.registry.*;
  import  java.rmi.server.*;
  import  java.util.*;
  import  java.sql.*;
  
  /////////////////////////////////////
  import org.apache.stratum.jcs.auxiliary.behavior.*;
  import org.apache.stratum.jcs.engine.behavior.*;
  import org.apache.stratum.jcs.engine.control.*;
  import org.apache.stratum.jcs.engine.*;
  import org.apache.stratum.jcs.access.*;
  import org.apache.stratum.jcs.engine.control.Cache;
  import org.apache.stratum.jcs.auxiliary.disk.*;
  import org.apache.stratum.jcs.auxiliary.lateral.*;
  import org.apache.stratum.jcs.auxiliary.remote.*;
  import org.apache.stratum.jcs.auxiliary.remote.behavior.*;
  import org.apache.stratum.jcs.utils.log.*;
  
  ///////////////////////////////////////////////////////////////////////
  public class CompositeCacheManagerTester {
  
        /////////////////////////////////////////
    public static void main( String args[] ) {
  
      CompositeCacheManagerTester ccmt = new CompositeCacheManagerTester();
  
      String propsFile = "/cache.ccf";
      if ( args.length > 0 ) {
        propsFile = args[0];
      }
      CompositeCacheManager ccm = new CompositeCacheManager( propsFile );
  
    }
  
  
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to