FileDocCategorySizeDatePackage
JBCCache.javaAPI DocJBoss 4.2.110477Fri Jul 13 20:53:58 BST 2007org.jboss.ejb3.entity

JBCCache

public class JBCCache extends Object implements org.hibernate.cache.Cache
Subclass of the standard org.hibernate.cache.TreeCache used as a workaround until issues related to JBCLUSTER-150 are resolved in Hibernate.
author
Gavin King
author
Brian Stansberry

Fields Summary
private static final Log
log
private static final String
ITEM
private org.jboss.cache.TreeCache
cache
private final String
regionName
private final org.jboss.cache.Fqn
regionFqn
private final TransactionManager
transactionManager
private boolean
localWritesOnly
Constructors Summary
public JBCCache(org.jboss.cache.TreeCache cache, String regionName, String regionPrefix, TransactionManager transactionManager)


	     
                        
	  
		this.cache = cache;
		this.regionName = regionName;
        this.regionFqn = Fqn.fromString(SecondLevelCacheUtil.createRegionFqn(regionName, regionPrefix));
		this.transactionManager = transactionManager;
        if (cache.getUseRegionBasedMarshalling())
        {           
           localWritesOnly = StandardQueryCache.class.getName().equals(regionName);
           
           boolean fetchState = cache.getFetchInMemoryState();
           try
           {
              // We don't want a state transfer for the StandardQueryCache,
              // as it can include classes from multiple scoped classloaders
              if (localWritesOnly)
                 cache.setFetchInMemoryState(false);
              
              // We always activate
              activateCacheRegion(regionFqn.toString());
           }
           finally
           {
              // Restore the normal state transfer setting
              if (localWritesOnly)
                 cache.setFetchInMemoryState(fetchState);              
           }
        }
        else
        {
           log.debug("TreeCache is not configured for region based marshalling");
        }
	
Methods Summary
private voidactivateCacheRegion(java.lang.String regionName)

       String fqnString = regionFqn.toString();
       // FIXME -- find a way that doesn't involve this API
       if (cache.getMarshaller().isInactive(fqnString))
       {
          try
          {
             // Only register the classloader if it's not a shared region.  
             // If it's shared, no single classloader is valid
             if (!SecondLevelCacheUtil.isSharedClassLoaderRegion(regionName))
             {
                cache.registerClassLoader(fqnString, Thread.currentThread().getContextClassLoader());
             }
             cache.activateRegion(fqnString);
          }
          catch (Exception e)
          {
             throw new CacheException("Problem activating region " + regionName, e);
          }
       }
       else
       {
          log.debug("activateCacheRegion(): Region " + fqnString + " is already active");
       }
    
public voidclear()

		try {
			cache.remove( regionFqn );
		}
		catch (Exception e) {
			throw new CacheException(e);
		}
	
public voiddestroy()

		try {
			// NOTE : Hibernate's class uses evict() but that isn't recursive!
			//cache.evict( regionFqn );
            Option opt = new Option();
            opt.setCacheModeLocal(true);
            cache.remove(regionFqn, opt);
            
            if (cache.getUseRegionBasedMarshalling() && !SecondLevelCacheUtil.isSharedClassLoaderRegion(regionName))
            {
               inactivateCacheRegion();
            }
		}
        catch (CacheException e)
        {
           throw e;
        }
		catch( Exception e ) {
			throw new CacheException( e );
		}
	
public java.lang.Objectget(java.lang.Object key)

		Transaction tx = suspend();
		try {
			return read(key);
		}
		finally {
			resume( tx );
		}
	
public longgetElementCountInMemory()

		try {
			Set children = cache.getChildrenNames( regionFqn );
			return children == null ? 0 : children.size();
		}
		catch (Exception e) {
			throw new CacheException(e);
		}
	
public longgetElementCountOnDisk()

		return 0;
	
public java.lang.StringgetRegionName()

		return regionName;
	
public longgetSizeInMemory()

		return -1;
	
public intgetTimeout()

		return 600; //60 seconds
	
private voidinactivateCacheRegion()

       String fqnString = regionFqn.toString();
       // FIXME -- find a way that doesn't involve this API
       if (!cache.getMarshaller().isInactive(fqnString))
       {
          try
          {
             cache.inactivateRegion(fqnString);
             cache.unregisterClassLoader(fqnString);
          }
          catch (Exception e)
          {
             throw new CacheException("Problem activating region " + fqnString, e);
          }
       }     
       else
       {
          log.debug("inactivateCacheRegion(): Region " + fqnString + " is already inactive");
       }
    
public voidlock(java.lang.Object key)

		throw new UnsupportedOperationException( "TreeCache is a fully transactional cache: " + regionName );
	
public longnextTimestamp()

		return System.currentTimeMillis() / 100;
	
public voidput(java.lang.Object key, java.lang.Object value)

		Transaction tx = suspend();
		try {
           if (localWritesOnly) {
              Option option = new Option();
              option.setCacheModeLocal(true);
              // Overloaded method isn't available, so have to use InvocationContext
              cache.getInvocationContext().setOptionOverrides(option);
              try {
                  // do the failfast put outside the scope of the JTA txn
                  cache.putFailFast( new Fqn( regionFqn, key ), ITEM, value, 0 );
              }
              finally {
                 cache.getInvocationContext().setOptionOverrides(null);
              }
           }
           else {               
               //do the failfast put outside the scope of the JTA txn
			   cache.putFailFast( new Fqn( regionFqn, key ), ITEM, value, 0 );
           }
		}
		catch (TimeoutException te) {
			//ignore!
			log.debug("ignoring write lock acquisition failure");
		}
		catch (Exception e) {
			throw new CacheException(e);
		}
		finally {
			resume( tx );
		}
	
public java.lang.Objectread(java.lang.Object key)

		try {
			return cache.get( new Fqn( regionFqn, key ), ITEM );
		}
		catch (Exception e) {
			throw new CacheException(e);
		}
	
public voidremove(java.lang.Object key)

		try {
           if (localWritesOnly) {
              Option option = new Option();
              option.setCacheModeLocal(true);
              cache.remove( new Fqn( regionFqn, key ), option );
           }
           else {               
               cache.remove( new Fqn( regionFqn, key ) );
           }
		}
		catch (Exception e) {
			throw new CacheException(e);
		}
	
private voidresume(javax.transaction.Transaction tx)

		try {
			if (tx!=null) transactionManager.resume(tx);
		}
		catch (Exception e) {
			throw new CacheException("Could not resume transaction", e);
		}
	
private javax.transaction.Transactionsuspend()

		Transaction tx = null;
		try {
			if ( transactionManager!=null ) {
				tx = transactionManager.suspend();
			}
		}
		catch (SystemException se) {
			throw new CacheException("Could not suspend transaction", se);
		}
		return tx;
	
public java.util.MaptoMap()

		try {
			Map result = new HashMap();
			Set childrenNames = cache.getChildrenNames( regionFqn );
			if (childrenNames != null) {
				Iterator iter = childrenNames.iterator();
				while ( iter.hasNext() ) {
					Object key = iter.next();
					result.put( 
							key, 
							cache.get( new Fqn( regionFqn, key ), ITEM )
						);
				}
			}
			return result;
		}
		catch (Exception e) {
			throw new CacheException(e);
		}
	
public java.lang.StringtoString()

		return "JBCCache(" + regionName + ')";
	
public voidunlock(java.lang.Object key)

		throw new UnsupportedOperationException( "TreeCache is a fully transactional cache: " + regionName );
	
public voidupdate(java.lang.Object key, java.lang.Object value)

		try {
            if (localWritesOnly) {
               Option option = new Option();
               option.setCacheModeLocal(true);
               cache.put( new Fqn( regionFqn, key ), ITEM, value, option );
            }
            else {               
                cache.put( new Fqn( regionFqn, key ), ITEM, value );
            }
		}
		catch (Exception e) {
			throw new CacheException(e);
		}