[jboss-cvs] JBossAS SVN: r58550 - trunk/ejb3/src/main/org/jboss/ejb3/entity
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Sat Nov 18 06:17:52 EST 2006
Author: bstansberry at jboss.com
Date: 2006-11-18 06:17:49 -0500 (Sat, 18 Nov 2006)
New Revision: 58550
Added:
trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java
trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCacheFactory.java
trunk/ejb3/src/main/org/jboss/ejb3/entity/OptimisticJBCCache.java
trunk/ejb3/src/main/org/jboss/ejb3/entity/TransactionalCacheFactory.java
Log:
Add Hibernate Cache impls that can talk to JBC 2.0
Added: trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java 2006-11-18 11:17:07 UTC (rev 58549)
+++ trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCache.java 2006-11-18 11:17:49 UTC (rev 58550)
@@ -0,0 +1,228 @@
+package org.jboss.ejb3.entity;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.OptimisticCache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.Node;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.lock.TimeoutException;
+
+/**
+ * {@link Cache} implementation that uses a 2.x or later release of JBoss Cache.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1.1 $
+ */
+public class JBCCache implements Cache
+{
+
+ private static final Log log = LogFactory.getLog(JBCCache.class);
+
+ private static final String ITEM = "item";
+
+ private org.jboss.cache.Cache cache;
+ private final String regionName;
+ private final Fqn regionFqn;
+ private final TransactionManager transactionManager;
+
+ public JBCCache(org.jboss.cache.Cache cache, String regionName, TransactionManager transactionManager)
+ throws CacheException {
+ this.cache = cache;
+ this.regionName = regionName;
+ this.regionFqn = Fqn.fromString( regionName.replace( '.', '/' ) );
+ this.transactionManager = transactionManager;
+ }
+
+ public Object get(Object key) throws CacheException {
+ Transaction tx = suspend();
+ try {
+ return read(key);
+ }
+ finally {
+ resume( tx );
+ }
+ }
+
+ public Object read(Object key) throws CacheException {
+ try {
+ return cache.get( new Fqn( regionFqn, key ), ITEM );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void update(Object key, Object value) throws CacheException {
+ try {
+ cache.put( new Fqn( regionFqn, key ), ITEM, value );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void put(Object key, Object value) throws CacheException {
+ Transaction tx = suspend();
+ try {
+ //do the failfast put outside the scope of the JTA txn
+ cache.putForExternalRead(new Fqn( regionFqn, key ), ITEM, value);
+ }
+ catch (TimeoutException te) {
+ //ignore!
+ log.debug("ignoring write lock acquisition failure");
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally {
+ resume( tx );
+ }
+ }
+
+ private void resume(Transaction tx) {
+ try {
+ if (tx!=null) transactionManager.resume(tx);
+ }
+ catch (Exception e) {
+ throw new CacheException("Could not resume transaction", e);
+ }
+ }
+
+ private Transaction suspend() {
+ Transaction tx = null;
+ try {
+ if ( transactionManager!=null ) {
+ tx = transactionManager.suspend();
+ }
+ }
+ catch (SystemException se) {
+ throw new CacheException("Could not suspend transaction", se);
+ }
+ return tx;
+ }
+
+ public void remove(Object key) throws CacheException {
+ try {
+ cache.removeNode( new Fqn( regionFqn, key ) );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void clear() throws CacheException {
+ try {
+ cache.removeNode( regionFqn );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void destroy() throws CacheException {
+ try {
+ // NOTE : evict() operates locally only (i.e., does not propogate
+ // to any other nodes in the potential cluster). This is
+ // exactly what is needed when we destroy() here; destroy() is used
+ // as part of the process of shutting down a SessionFactory; thus
+ // these removals should not be propogated
+ // FIXME NPE bug in 2.0.0.ALPHA1, so we don't use evict 'til fixed
+// cache.evict( regionFqn, true );
+ InvocationContext ctx = cache.getInvocationContext();
+ Option opt = new Option();
+ opt.setCacheModeLocal(true);
+ ctx.setOptionOverrides(opt);
+ cache.removeNode( regionFqn );
+ }
+ catch( Exception e ) {
+ throw new CacheException( e );
+ }
+ }
+
+ public void lock(Object key) throws CacheException {
+ throw new UnsupportedOperationException( "TreeCache is a fully transactional cache" + regionName );
+ }
+
+ public void unlock(Object key) throws CacheException {
+ throw new UnsupportedOperationException( "TreeCache is a fully transactional cache: " + regionName );
+ }
+
+ public long nextTimestamp() {
+ return System.currentTimeMillis() / 100;
+ }
+
+ public int getTimeout() {
+ return 600; //60 seconds
+ }
+
+ public String getRegionName() {
+ return regionName;
+ }
+
+ public long getSizeInMemory() {
+ return -1;
+ }
+
+ public long getElementCountInMemory() {
+ try {
+ Set children = getChildrenNames();
+ return children == null ? 0 : children.size();
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public long getElementCountOnDisk() {
+ return 0;
+ }
+
+ public Map toMap() {
+ try {
+ Map result = new HashMap();
+ Set childrenNames = getChildrenNames();
+ 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);
+ }
+ }
+
+ private Set getChildrenNames()
+ {
+ try {
+ Node base = cache.getChild( regionFqn );
+ return base == null ? null : base.getChildrenNames();
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public String toString() {
+ return "JBCCache(" + regionName + ')';
+ }
+}
Added: trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCacheFactory.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCacheFactory.java 2006-11-18 11:17:07 UTC (rev 58549)
+++ trunk/ejb3/src/main/org/jboss/ejb3/entity/JBCCacheFactory.java 2006-11-18 11:17:49 UTC (rev 58550)
@@ -0,0 +1,51 @@
+package org.jboss.ejb3.entity;
+
+import java.util.Properties;
+
+import javax.management.ObjectName;
+
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheException;
+import org.jboss.cache.jmx.CacheJmxWrapperMBean;
+import org.jboss.ejb3.tx.TxUtil;
+import org.jboss.mx.util.MBeanProxyExt;
+import org.jboss.mx.util.MBeanServerLocator;
+
+class JBCCacheFactory extends TransactionalCacheFactory
+{
+ private org.jboss.cache.Cache cache;
+ private boolean optimistic;
+
+ JBCCacheFactory()
+ {
+
+ }
+
+ protected void configure(Properties hibernateConfig)
+ {
+ try
+ {
+ ObjectName mbeanObjectName = new ObjectName((String) hibernateConfig.get("hibernate.treecache.mbean.object_name"));
+ CacheJmxWrapperMBean mbean = (CacheJmxWrapperMBean) MBeanProxyExt.create(CacheJmxWrapperMBean.class, mbeanObjectName, MBeanServerLocator.locateJBoss());
+ cache = mbean.getCache();
+ optimistic = cache.getConfiguration().isNodeLockingOptimistic();
+ }
+ catch (Exception e)
+ {
+ throw new CacheException(e);
+ }
+ }
+
+ public Cache buildCache(String regionName, Properties properties) throws CacheException
+ {
+// if (optimistic)
+// {
+// return new OptimisticJBCCache(cache, regionName);
+// }
+// else
+// {
+ return new JBCCache(cache, regionName, TxUtil.getTransactionManager());
+// }
+ }
+
+}
Added: trunk/ejb3/src/main/org/jboss/ejb3/entity/OptimisticJBCCache.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/entity/OptimisticJBCCache.java 2006-11-18 11:17:07 UTC (rev 58549)
+++ trunk/ejb3/src/main/org/jboss/ejb3/entity/OptimisticJBCCache.java 2006-11-18 11:17:49 UTC (rev 58550)
@@ -0,0 +1,409 @@
+package org.jboss.ejb3.entity;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.OptimisticCache;
+import org.hibernate.cache.OptimisticCacheSource;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.Node;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.lock.TimeoutException;
+import org.jboss.cache.optimistic.DataVersion;
+
+public class OptimisticJBCCache implements OptimisticCache
+{
+ // todo : eventually merge this with TreeCache and just add optional opt-lock support there.
+
+ private static final Log log = LogFactory.getLog( OptimisticJBCCache.class);
+
+ private static final String ITEM = "item";
+
+ private static final Option NONLOCKING_OPTION = new Option();
+ private static final Option FAIL_SILENT_OPTION = new Option();
+ private static final Option FAIL_SILENT_NONLOCKING_OPTION = new Option();
+
+ static
+ {
+ FAIL_SILENT_OPTION.setFailSilently( true );
+
+ FAIL_SILENT_NONLOCKING_OPTION.setFailSilently( true );
+ FAIL_SILENT_NONLOCKING_OPTION.setDataVersion( NonLockingDataVersion.INSTANCE );
+ NONLOCKING_OPTION.setDataVersion( NonLockingDataVersion.INSTANCE );
+ }
+
+ private org.jboss.cache.Cache cache;
+ private final String regionName;
+ private final Fqn regionFqn;
+ private OptimisticCacheSource source;
+
+ public OptimisticJBCCache(org.jboss.cache.Cache cache, String regionName)
+ throws CacheException {
+ this.cache = cache;
+ this.regionName = regionName;
+ this.regionFqn = Fqn.fromString( regionName.replace( '.', '/' ) );
+ }
+
+
+ // OptimisticCache impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void setSource(OptimisticCacheSource source) {
+ this.source = source;
+ }
+
+ public void writeInsert(Object key, Object value, Object currentVersion) {
+ writeUpdate( key, value, currentVersion, null );
+ }
+
+ public void writeUpdate(Object key, Object value, Object currentVersion, Object previousVersion)
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+ Option option = new Option();
+ DataVersion dv = ( source != null && source.isVersioned() )
+ ? new DataVersionAdapter( currentVersion, previousVersion, source.getVersionComparator(), source.toString() )
+ : NonLockingDataVersion.INSTANCE;
+ option.setDataVersion( dv );
+
+ ctx.setOptionOverrides(option);
+ cache.put( new Fqn( regionFqn, key ), ITEM, value);
+ }
+ catch ( Exception e ) {
+ throw new CacheException( e );
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+ public void writeLoad(Object key, Object value, Object currentVersion)
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+
+ ctx.setOptionOverrides(FAIL_SILENT_NONLOCKING_OPTION);
+ cache.remove( new Fqn( regionFqn, key ), "ITEM");
+
+ Option option = new Option();
+ option.setFailSilently( true );
+ DataVersion dv = ( source != null && source.isVersioned() )
+ ? new DataVersionAdapter( currentVersion, currentVersion, source.getVersionComparator(), source.toString() )
+ : NonLockingDataVersion.INSTANCE;
+ option.setDataVersion( dv );
+
+ ctx = cache.getInvocationContext();
+ ctx.setOptionOverrides(option);
+ cache.put( new Fqn( regionFqn, key ), ITEM, value);
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+
+ // Cache impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public Object get(Object key) throws CacheException
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+
+// ctx.setOptionOverrides(FAIL_SILENT_NONLOCKING_OPTION);
+ ctx.setOptionOverrides(FAIL_SILENT_OPTION);
+ return cache.get( new Fqn( regionFqn, key ), ITEM);
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+ public Object read(Object key) throws CacheException {
+ try {
+ return cache.get( new Fqn( regionFqn, key ), ITEM );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public void update(Object key, Object value) throws CacheException
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+ ctx.setOptionOverrides(NONLOCKING_OPTION);
+ cache.put( new Fqn( regionFqn, key ), ITEM, value );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+ public void put(Object key, Object value) throws CacheException
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+ log.trace( "performing put() into region [" + regionName + "]" );
+ // do the put outside the scope of the JTA txn
+ ctx.setOptionOverrides(FAIL_SILENT_NONLOCKING_OPTION);
+ cache.put( new Fqn( regionFqn, key ), ITEM, value );
+ }
+ catch (TimeoutException te) {
+ //ignore!
+ log.debug("ignoring write lock acquisition failure");
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+ public void remove(Object key) throws CacheException
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+ // tree cache in optimistic mode seems to have as very difficult
+ // time with remove calls on non-existent nodes (NPEs)...
+ if ( cache.get( new Fqn( regionFqn, key ), ITEM ) != null ) {
+ Option option = new Option();
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
+ ctx.setOptionOverrides(option);
+ cache.removeNode( new Fqn( regionFqn, key ) );
+ }
+ else {
+ log.trace( "skipping remove() call as the underlying node did not seem to exist" );
+ }
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+ public void clear() throws CacheException
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+ Option option = new Option();
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
+ ctx.setOptionOverrides(option);
+ cache.removeNode( regionFqn );
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+ public void destroy() throws CacheException
+ {
+ InvocationContext ctx = cache.getInvocationContext();
+ Option existing = ctx.getOptionOverrides();
+ try {
+ Option option = new Option();
+ option.setCacheModeLocal( true );
+ option.setFailSilently( true );
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
+ ctx.setOptionOverrides(option);
+ cache.removeNode( regionFqn );
+ }
+ catch( Exception e ) {
+ throw new CacheException( e );
+ }
+ finally
+ {
+ ctx.setOptionOverrides(existing);
+ }
+ }
+
+ public void lock(Object key) throws CacheException {
+ throw new UnsupportedOperationException( "TreeCache is a fully transactional cache" + regionName );
+ }
+
+ public void unlock(Object key) throws CacheException {
+ throw new UnsupportedOperationException( "TreeCache is a fully transactional cache: " + regionName );
+ }
+
+ public long nextTimestamp() {
+ return System.currentTimeMillis() / 100;
+ }
+
+ public int getTimeout() {
+ return 600; //60 seconds
+ }
+
+ public String getRegionName() {
+ return regionName;
+ }
+
+ public long getSizeInMemory() {
+ return -1;
+ }
+
+ public long getElementCountInMemory() {
+ try {
+ Set children = getChildrenNames();
+ return children == null ? 0 : children.size();
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public long getElementCountOnDisk() {
+ return 0;
+ }
+
+ public Map toMap() {
+ try {
+ Map result = new HashMap();
+ Set childrenNames = getChildrenNames();
+ 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);
+ }
+ }
+
+ private Set getChildrenNames()
+ {
+ try {
+ Node base = cache.getChild( regionFqn );
+ return base == null ? null : base.getChildrenNames();
+ }
+ catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
+
+ public String toString() {
+ return "OptimisticTreeCache(" + regionName + ')';
+ }
+
+ public static class DataVersionAdapter implements DataVersion {
+ private final Object currentVersion;
+ private final Object previousVersion;
+ private final Comparator versionComparator;
+ private final String sourceIdentifer;
+
+ public DataVersionAdapter(Object currentVersion, Object previousVersion, Comparator versionComparator, String sourceIdentifer) {
+ this.currentVersion = currentVersion;
+ this.previousVersion = previousVersion;
+ this.versionComparator = versionComparator;
+ this.sourceIdentifer = sourceIdentifer;
+ log.trace( "created " + this );
+ }
+
+ /**
+ * newerThan() call is dispatched against the DataVersion currently
+ * associated with the node; the passed dataVersion param is the
+ * DataVersion associated with the data we are trying to put into
+ * the node.
+ * <p/>
+ * we are expected to return true in the case where we (the current
+ * node DataVersion) are newer that then incoming value. Returning
+ * true here essentially means that a optimistic lock failure has
+ * occured (because conversely, the value we are trying to put into
+ * the node is "older than" the value already there...)
+ */
+ public boolean newerThan(DataVersion dataVersion) {
+ log.trace( "checking [" + this + "] against [" + dataVersion + "]" );
+ if ( dataVersion instanceof CircumventChecksDataVersion ) {
+ log.trace( "skipping lock checks..." );
+ return false;
+ }
+ else if ( dataVersion instanceof NonLockingDataVersion ) {
+ // can happen because of the multiple ways Cache.remove()
+ // can be invoked :(
+ log.trace( "skipping lock checks..." );
+ return false;
+ }
+ DataVersionAdapter other = ( DataVersionAdapter ) dataVersion;
+ if ( other.previousVersion == null ) {
+ log.warn( "Unexpected optimistic lock check on inserting data" );
+ // work around the "feature" where tree cache is validating the
+ // inserted node during the next transaction. no idea...
+ if ( this == dataVersion ) {
+ log.trace( "skipping lock checks due to same DV instance" );
+ return false;
+ }
+ }
+ return versionComparator.compare( currentVersion, other.previousVersion ) >= 1;
+ }
+
+ public String toString() {
+ return super.toString() + " [current=" + currentVersion + ", previous=" + previousVersion + ", src=" + sourceIdentifer + "]";
+ }
+ }
+
+ /**
+ * Used in regions where no locking should ever occur. This includes query-caches,
+ * update-timestamps caches, collection caches, and entity caches where the entity
+ * is not versioned.
+ */
+ public static class NonLockingDataVersion implements DataVersion {
+ public static final DataVersion INSTANCE = new NonLockingDataVersion();
+ public boolean newerThan(DataVersion dataVersion) {
+ log.trace( "non locking lock check...");
+ return false;
+ }
+ }
+
+ /**
+ * Used to signal to a DataVersionAdapter to simply not perform any checks. This
+ * is currently needed for proper handling of remove() calls for entity cache regions
+ * (we do not know the version info...).
+ */
+ public static class CircumventChecksDataVersion implements DataVersion {
+ public static final DataVersion INSTANCE = new CircumventChecksDataVersion();
+ public boolean newerThan(DataVersion dataVersion) {
+ throw new CacheException( "optimistic locking checks should never happen on CircumventChecksDataVersion" );
+ }
+ }
+
+}
Added: trunk/ejb3/src/main/org/jboss/ejb3/entity/TransactionalCacheFactory.java
===================================================================
--- trunk/ejb3/src/main/org/jboss/ejb3/entity/TransactionalCacheFactory.java 2006-11-18 11:17:07 UTC (rev 58549)
+++ trunk/ejb3/src/main/org/jboss/ejb3/entity/TransactionalCacheFactory.java 2006-11-18 11:17:49 UTC (rev 58550)
@@ -0,0 +1,76 @@
+package org.jboss.ejb3.entity;
+
+import java.util.Properties;
+
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheException;
+import org.jboss.cache.Version;
+
+public abstract class TransactionalCacheFactory
+{
+
+ /**
+ * Gets and configures a concrete TransactionalCacheFactory suitable for
+ * interoperation with the version of JBoss Cache visible on the classpath.
+ *
+ * @param hibernateConfig properties to use to {@link #configure(Properties) configure}
+ * the factory.
+ * @return the factory
+ *
+ * @throws CacheException
+ */
+ public static TransactionalCacheFactory getFactory(Properties hibernateConfig) throws CacheException
+ {
+ String factoryClass = null;
+ short version = Version.getVersionShort();
+ if (version >= Version.getVersionShort("2.0.0.GA") || version <= 0)
+ {
+ factoryClass = "org.jboss.ejb3.entity.JBCCacheFactory";
+ }
+ else
+ {
+ // TODO write a factory for the old hibernate stuff
+ // needs to be in a separate code tree from JBCCacheFactory as
+ // TreeCacheMBean is no longer available in 2.0
+ throw new IllegalStateException("Cannot create factory for JBC 1.x");
+ }
+
+ try
+ {
+ Class clazz = Thread.currentThread().getContextClassLoader().loadClass(factoryClass);
+ TransactionalCacheFactory factory = (TransactionalCacheFactory) clazz.newInstance();
+ factory.configure(hibernateConfig);
+
+ return factory;
+ }
+ catch (CacheException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new CacheException(e);
+ }
+
+ }
+
+ /**
+ * Construct and configure the Cache representation of a named cache region.
+ *
+ * @param regionName the name of the cache region
+ * @param properties configuration settings
+ * @return The Cache representation of the named cache region.
+ * @throws org.hibernate.cache.CacheException
+ * Indicates an error building the cache region.
+ */
+ public abstract Cache buildCache(String regionName, Properties properties) throws CacheException;
+
+ /**
+ * Configures the factory using the Hibernate configuration properties.
+ * Called by {@link #getFactory(Properties)}.
+ *
+ * @param hibernateConfig the Hibernate configuration properties
+ */
+ protected abstract void configure(Properties hibernateConfig);
+
+}
More information about the jboss-cvs-commits
mailing list