diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java index f471237f3d..6ecee007eb 100644 --- a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java @@ -63,6 +63,14 @@ public abstract class BasicRegionAdapter implements Region { return regionName; } + public Cache getCacheInstance() { + return jbcCache; + } + + public Fqn getRegionFqn() { + return regionFqn; + } + public void destroy() throws CacheException { try { // NOTE : this is being used from the process of shutting down a diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java index 65f54f94ba..3a4ac9c218 100644 --- a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java @@ -25,6 +25,7 @@ import org.hibernate.cache.QueryResultsRegion; import org.hibernate.cache.RegionFactory; import org.hibernate.cache.TimestampsRegion; import org.hibernate.cache.jbc2.builder.InvalidationCacheInstanceManager; +import org.hibernate.cache.jbc2.collection.CollectionRegionImpl; import org.hibernate.cache.jbc2.entity.EntityRegionImpl; import org.hibernate.cfg.Settings; @@ -74,7 +75,7 @@ public class JBossCacheRegionFactory implements RegionFactory { String regionName, Properties properties, CacheDataDescription metadata) throws CacheException { - return null; + return new CollectionRegionImpl( cacheInstanceManager.getCollectionCacheInstance(), regionName, metadata ); } public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException { diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/TransactionalDataRegionAdapter.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/TransactionalDataRegionAdapter.java new file mode 100644 index 0000000000..d33fb4f102 --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/TransactionalDataRegionAdapter.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Steve Ebersole + */ +package org.hibernate.cache.jbc2; + +import org.jboss.cache.Cache; + +import org.hibernate.cache.TransactionalDataRegion; +import org.hibernate.cache.CacheDataDescription; + +/** + * {@inheritDoc} + * + * @author Steve Ebersole + */ +public class TransactionalDataRegionAdapter extends BasicRegionAdapter implements TransactionalDataRegion { + protected final CacheDataDescription metadata; + + public TransactionalDataRegionAdapter(Cache jbcCache, String regionName, CacheDataDescription metadata) { + super( jbcCache, regionName ); + this.metadata = metadata; + } + + /** + * Here, for JBossCache, we consider the cache to be transaction aware if the underlying + * cache instance has a refernece to the transaction manager. + */ + public boolean isTransactionAware() { + return jbcCache.getConfiguration().getRuntimeConfig().getTransactionManager() != null; + } + + /** + * {@inheritDoc} + */ + public CacheDataDescription getCacheDataDescription() { + return metadata; + } +} diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java index e573d93256..d9f628117d 100644 --- a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java @@ -16,22 +16,25 @@ package org.hibernate.cache.jbc2.builder; import java.util.Properties; - import javax.transaction.TransactionManager; -import org.jboss.cache.Cache; -import org.jboss.cache.DefaultCacheFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jboss.cache.Cache; +import org.jboss.cache.DefaultCacheFactory; -import org.hibernate.util.PropertiesHelper; +import org.hibernate.cache.CacheException; import org.hibernate.cache.jbc2.CacheInstanceManager; +import org.hibernate.cache.jbc2.util.CacheModeHelper; import org.hibernate.cfg.Settings; +import org.hibernate.util.PropertiesHelper; /** - * A {@link org.hibernate.cache.jbc2.CacheInstanceManager} implementation where we use a single cache instance + * A {@link CacheInstanceManager} implementation where we use a single cache instance * we assume to be configured for invalidation if operating on a cluster. Under that * assumption, we can store all data into the same {@link Cache} instance. + *
+ * todo : this is built on the assumption that JBC clustered invalidation is changed to keep the "cache node" around on the other "cluster nodes" * * @author Steve Ebersole */ @@ -77,6 +80,9 @@ public class InvalidationCacheInstanceManager implements CacheInstanceManager { * {@inheritDoc} */ public Cache getQueryCacheInstance() { + if ( CacheModeHelper.isClusteredInvalidation( cache ) ) { + throw new CacheException( "Query cache not supported for clustered invalidation" ); + } return cache; } @@ -84,6 +90,9 @@ public class InvalidationCacheInstanceManager implements CacheInstanceManager { * {@inheritDoc} */ public Cache getTimestampsCacheInstance() { + if ( CacheModeHelper.isClusteredInvalidation( cache ) ) { + throw new CacheException( "Query cache not supported for clustered invalidation" ); + } return cache; } diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java index 7c2ed787ac..7a59e77c9c 100644 --- a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java @@ -30,9 +30,11 @@ import org.hibernate.util.PropertiesHelper; /** * Here we build separate {@link Cache} instances for each type of region, but - * using the jgroups multiplexer under the covers to re-use the same group comm - * stack. - * + * using the jgroups multiplexer under the covers to re-use the same group + * communication stack. + * + * todo : this can get simplified once JBC implemants their "configuration factory" (the stuff akin to channel factory) + * * @author Steve Ebersole */ public class MultiplexingCacheInstanceManager implements CacheInstanceManager { diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java new file mode 100644 index 0000000000..426f908bed --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Steve Ebersole + */ +package org.hibernate.cache.jbc2.collection; + +import org.jboss.cache.Cache; + +import org.hibernate.cache.CacheDataDescription; +import org.hibernate.cache.CacheException; +import org.hibernate.cache.CollectionRegion; +import org.hibernate.cache.access.AccessType; +import org.hibernate.cache.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter; + +/** + * Defines the behavior of the collection cache regions for JBossCache. + * + * @author Steve Ebersole + */ +public class CollectionRegionImpl extends TransactionalDataRegionAdapter implements CollectionRegion { + public CollectionRegionImpl(Cache jbcCache, String regionName, CacheDataDescription metadata) { + super( jbcCache, regionName, metadata ); + } + + public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException { + if ( AccessType.READ_ONLY.equals( accessType ) ) { + return new ReadOnlyAccess( this ); + } + if ( AccessType.TRANSACTIONAL.equals( accessType ) ) { + return new TransactionalAccess( this ); + } + + // todo : add support for READ_WRITE ( + NONSTRICT_READ_WRITE ??? ) + + throw new CacheException( "unsupported access type [" + accessType.getName() + "]" ); + } +} diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/ReadOnlyAccess.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/ReadOnlyAccess.java new file mode 100644 index 0000000000..5ee9daca31 --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/ReadOnlyAccess.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Steve Ebersole + */ +package org.hibernate.cache.jbc2.collection; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.hibernate.cache.access.SoftLock; +import org.hibernate.cache.CacheException; + +/** + * This defines the strategy for transactional access to enity data in JBossCache using its 2.x APIs + * + * read-only access to a JBossCache really is still transactional, just with + * the extra semantic or guarentee that we will not update data. + * + * @author Steve Ebersole + */ +public class ReadOnlyAccess extends TransactionalAccess { + private static final Log log = LogFactory.getLog( ReadOnlyAccess.class ); + + public ReadOnlyAccess(CollectionRegionImpl region) { + super( region ); + } + + public SoftLock lockItem(Object key, Object version) throws CacheException { + throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); + } + + public SoftLock lockRegion() throws CacheException { + throw new UnsupportedOperationException( "Illegal attempt to edit read only region" ); + } + + public void unlockItem(Object key, SoftLock lock) throws CacheException { + log.error( "Illegal attempt to edit read only item" ); + } + + public void unlockRegion(SoftLock lock) throws CacheException { + log.error( "Illegal attempt to edit read only region" ); + } + + public boolean update( + Object key, + Object value, + Object currentVersion, + Object previousVersion) throws CacheException { + throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); + } + + public boolean afterUpdate( + Object key, + Object value, + Object currentVersion, + Object previousVersion, + SoftLock lock) throws CacheException { + throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); + } +} diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java new file mode 100644 index 0000000000..c98f667639 --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Steve Ebersole + */ +package org.hibernate.cache.jbc2.collection; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.hibernate.cache.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.access.SoftLock; +import org.hibernate.cache.CollectionRegion; +import org.hibernate.cache.CacheException; + +/** + * todo : implement + * + * @author Steve Ebersole + */ +public class TransactionalAccess implements CollectionRegionAccessStrategy { + private static final Log log = LogFactory.getLog( TransactionalAccess.class ); + + private final CollectionRegionImpl region; + + public TransactionalAccess(CollectionRegionImpl region) { + this.region = region; + } + + public CollectionRegion getRegion() { + return region; + } + + public Object get(Object key, long txTimestamp) throws CacheException { + return null; + } + + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException { + return false; + } + + public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride) + throws CacheException { + return false; + } + + public SoftLock lockItem(Object key, Object version) throws CacheException { + return null; + } + + public SoftLock lockRegion() throws CacheException { + return null; + } + + public void unlockItem(Object key, SoftLock lock) throws CacheException { + } + + public void unlockRegion(SoftLock lock) throws CacheException { + } + + public void remove(Object key) throws CacheException { + } + + public void removeAll() throws CacheException { + } + + public void evict(Object key) throws CacheException { + } + + public void evictAll() throws CacheException { + } +} diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java index e7734b6a7d..b7c0b8402b 100644 --- a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java @@ -16,63 +16,38 @@ package org.hibernate.cache.jbc2.entity; import org.jboss.cache.Cache; -import org.jboss.cache.Fqn; import org.hibernate.cache.CacheDataDescription; import org.hibernate.cache.CacheException; import org.hibernate.cache.EntityRegion; import org.hibernate.cache.access.AccessType; import org.hibernate.cache.access.EntityRegionAccessStrategy; -import org.hibernate.cache.jbc2.BasicRegionAdapter; - +import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter; /** * Defines the behavior of the entity cache regions for JBossCache. * * @author Steve Ebersole */ -public class EntityRegionImpl extends BasicRegionAdapter implements EntityRegion { - private final CacheDataDescription metadata; +public class EntityRegionImpl extends TransactionalDataRegionAdapter implements EntityRegion { public EntityRegionImpl(Cache jbcCache, String regionName, CacheDataDescription metadata) { - super( jbcCache, regionName ); - this.metadata = metadata; + super( jbcCache, regionName, metadata ); } /** * {@inheritDoc} */ public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException { - // todo : allow the other strategies, which will require a non-transactional cache instance - if ( ! ( AccessType.READ_ONLY.equals( accessType ) || AccessType.TRANSACTIONAL.equals( accessType ) ) ) { - throw new CacheException( - "TreeCacheRegionFactory only supports " + AccessType.READ_ONLY.getName() + " or " + - AccessType.TRANSACTIONAL + " access strategies [" + accessType.getName() + "]" - ); + if ( AccessType.READ_ONLY.equals( accessType ) ) { + return new ReadOnlyAccess( this ); + } + if ( AccessType.TRANSACTIONAL.equals( accessType ) ) { + return new TransactionalAccess( this ); } - return null; - } - /** - * Here, for JBossCache, we consider the cache to be transaction aware if the underlying - * cache instance has a refernece to the transaction manager. - */ - public boolean isTransactionAware() { - return jbcCache.getConfiguration().getRuntimeConfig().getTransactionManager() != null; - } + // todo : add support for READ_WRITE ( + NONSTRICT_READ_WRITE ??? ) - /** - * {@inheritDoc} - */ - public CacheDataDescription getCacheDataDescription() { - return metadata; - } - - Cache getCacheInstance() { - return jbcCache; - } - - Fqn getRegionFqn() { - return regionFqn; + throw new CacheException( "unsupported access type [" + accessType.getName() + "]" ); } } diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/ReadOnlyAccess.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/ReadOnlyAccess.java index 0bf69385ed..600c135719 100644 --- a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/ReadOnlyAccess.java +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/ReadOnlyAccess.java @@ -15,99 +15,41 @@ */ package org.hibernate.cache.jbc2.entity; -import org.jboss.cache.Fqn; -import org.jboss.cache.lock.TimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.hibernate.cache.access.EntityRegionAccessStrategy; import org.hibernate.cache.access.SoftLock; -import org.hibernate.cache.EntityRegion; import org.hibernate.cache.CacheException; /** - * {@inheritDoc} + * This defines the strategy for transactional access to enity data in JBossCache using its 2.x APIs + * + * read-only access to a JBossCache really is still transactional, just with + * the extra semantic or guarentee that we will not update data. * * @author Steve Ebersole */ -public class ReadOnlyAccess implements EntityRegionAccessStrategy { +public class ReadOnlyAccess extends TransactionalAccess { private static final Log log = LogFactory.getLog( ReadOnlyAccess.class ); - private final EntityRegionImpl region; - public ReadOnlyAccess(EntityRegionImpl region) { - this.region = region; - } - - public EntityRegion getRegion() { - return region; - } - - public Object get(Object key, long txTimestamp) throws CacheException { - try { - return region.getCacheInstance().get( region.getRegionFqn(), EntityRegionImpl.ITEM ); - } - catch ( Exception e ) { - throw new CacheException( e ); - } - } - - public boolean putFromLoad( - Object key, - Object value, - long txTimestamp, - Object version) throws CacheException { - try { - region.getCacheInstance().putForExternalRead( region.getRegionFqn(), key, value ); - return true; - } - catch ( TimeoutException te) { - //ignore! - log.debug( "ignoring write lock acquisition failure" ); - return false; - } - catch ( Throwable t ) { - throw new CacheException( t ); - } - } - - public boolean putFromLoad( - Object key, - Object value, - long txTimestamp, - Object version, - boolean minimalPutOverride) throws CacheException { - return putFromLoad( key, value, txTimestamp, version ); + super( region ); } public SoftLock lockItem(Object key, Object version) throws CacheException { - throw new UnsupportedOperationException( "Illegal attempt to lock (edit) read only item" ); + throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } public SoftLock lockRegion() throws CacheException { - throw new UnsupportedOperationException( "Illegal attempt to lock (edit) read only region" ); + throw new UnsupportedOperationException( "Illegal attempt to edit read only region" ); } public void unlockItem(Object key, SoftLock lock) throws CacheException { - log.error( "Illegal attempt to lock (edit) read only item" ); + log.error( "Illegal attempt to edit read only item" ); } public void unlockRegion(SoftLock lock) throws CacheException { - log.error( "Illegal attempt to lock (edit) read only region" ); - } - - public boolean insert(Object key, Object value, Object version) throws CacheException { - try { - region.getCacheInstance().put( new Fqn( region.getRegionFqn(), key ), EntityRegionImpl.ITEM, value ); - } - catch (Exception e) { - throw new CacheException(e); - } - return true; - } - - public boolean afterInsert(Object key, Object value, Object version) throws CacheException { - return false; + log.error( "Illegal attempt to edit read only region" ); } public boolean update( @@ -115,7 +57,7 @@ public class ReadOnlyAccess implements EntityRegionAccessStrategy { Object value, Object currentVersion, Object previousVersion) throws CacheException { - throw new UnsupportedOperationException( "Illegal attempt to lock (edit) read only item" ); + throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } public boolean afterUpdate( @@ -124,34 +66,6 @@ public class ReadOnlyAccess implements EntityRegionAccessStrategy { Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException { - throw new UnsupportedOperationException( "Illegal attempt to lock (edit) read only item" ); - } - - public void remove(Object key) throws CacheException { - try { - region.getCacheInstance().remove( region.getRegionFqn(), key ); - } - catch ( Exception e ) { - throw new CacheException( e ); - } - } - - public void removeAll() throws CacheException { - try { - region.getCacheInstance().removeNode( region.getRegionFqn() ); - } - catch ( Exception e ) { - throw new CacheException( e ); - } - } - - public void evict(Object key) throws CacheException { - } - - public void evictAll() throws CacheException { - } - - public void destroy() { - region.destroy(); + throw new UnsupportedOperationException( "Illegal attempt to edit read only item" ); } } diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java new file mode 100644 index 0000000000..ace75d7add --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Steve Ebersole + */ +package org.hibernate.cache.jbc2.entity; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jboss.cache.Fqn; +import org.jboss.cache.lock.TimeoutException; + +import org.hibernate.cache.access.EntityRegionAccessStrategy; +import org.hibernate.cache.access.SoftLock; +import org.hibernate.cache.EntityRegion; +import org.hibernate.cache.CacheException; + +/** + * This defines the strategy for transactional access to enity data + * in JBossCache using its 2.x APIs + * + * @author Steve Ebersole + */ +public class TransactionalAccess implements EntityRegionAccessStrategy { + private static final Log log = LogFactory.getLog( TransactionalAccess.class ); + + private final EntityRegionImpl region; + + public TransactionalAccess(EntityRegionImpl region) { + this.region = region; + } + + public EntityRegion getRegion() { + return region; + } + + public Object get(Object key, long txTimestamp) throws CacheException { + try { + return region.getCacheInstance().get( region.getRegionFqn(), EntityRegionImpl.ITEM ); + } + catch ( Exception e ) { + throw new CacheException( e ); + } + } + + public boolean putFromLoad( + Object key, + Object value, + long txTimestamp, + Object version) throws CacheException { + try { + region.getCacheInstance().putForExternalRead( new Fqn( region.getRegionFqn(), key ), EntityRegionImpl.ITEM, value ); + return true; + } + catch ( TimeoutException te) { + //ignore! + log.debug( "ignoring write lock acquisition failure" ); + return false; + } + catch ( Throwable t ) { + throw new CacheException( t ); + } + } + + public boolean putFromLoad( + Object key, + Object value, + long txTimestamp, + Object version, + boolean minimalPutOverride) throws CacheException { + if ( minimalPutOverride && get( key, txTimestamp ) != null ) { + if ( log.isDebugEnabled() ) { + log.debug( "item already cached: " + key ); + } + return false; + } + return putFromLoad( key, value, txTimestamp, version ); + } + + public SoftLock lockItem(Object key, Object version) throws CacheException { + return null; + } + + public SoftLock lockRegion() throws CacheException { + return null; + } + + public void unlockItem(Object key, SoftLock lock) throws CacheException { + } + + public void unlockRegion(SoftLock lock) throws CacheException { + } + + public boolean insert(Object key, Object value, Object version) throws CacheException { + try { + region.getCacheInstance().put( new Fqn( region.getRegionFqn(), key ), EntityRegionImpl.ITEM, value ); + } + catch ( Throwable t ) { + throw new CacheException( t ); + } + return true; + } + + public boolean afterInsert(Object key, Object value, Object version) throws CacheException { + return false; + } + + public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) + throws CacheException { + try { + region.getCacheInstance().put( new Fqn( region.getRegionFqn(), key ), EntityRegionImpl.ITEM, value ); + } + catch ( Throwable t ) { + throw new CacheException( t ); + } + return true; + } + + public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) + throws CacheException { + return false; + } + + public void remove(Object key) throws CacheException { + try { + region.getCacheInstance().removeNode( new Fqn( region.getRegionFqn(), key ) ); + } + catch ( Exception e ) { + throw new CacheException( e ); + } + } + + public void removeAll() throws CacheException { + try { + region.getCacheInstance().removeNode( region.getRegionFqn() ); + } + catch ( Exception e ) { + throw new CacheException( e ); + } + } + + public void evict(Object key) throws CacheException { + remove( key ); + } + + public void evictAll() throws CacheException { + removeAll(); + } +} diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheModeHelper.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheModeHelper.java new file mode 100644 index 0000000000..1b3ec80665 --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheModeHelper.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Steve Ebersole + */ +package org.hibernate.cache.jbc2.util; + +import org.jboss.cache.Cache; +import org.jboss.cache.config.Configuration; + +/** + * Helper for dealing with JBossCache {@link Configuration.CacheMode}. + * + * @author Steve Ebersole + */ +public class CacheModeHelper { + /** + * Disallow external instantiation of CacheModeHelper. + */ + private CacheModeHelper() { + } + + /** + * Is this cache participating in a cluster with invalidation? + * + * @param cache The cache to check. + * @return True if the cache is configured for synchronous/asynchronous invalidation; false + * otherwise. + */ + public static boolean isClusteredInvalidation(Cache cache) { + return isClusteredInvalidation( cache.getConfiguration().getCacheMode() ); + } + + /** + * Does this cache mode indicate clustered invalidation? + * + * @param cacheMode The cache to check + * @return True if the cache mode is confiogured for synchronous/asynchronous invalidation; false + * otherwise. + */ + public static boolean isClusteredInvalidation(Configuration.CacheMode cacheMode) { + return cacheMode == Configuration.CacheMode.REPL_ASYNC || cacheMode == Configuration.CacheMode.REPL_SYNC; + } +} diff --git a/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java b/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java index f75c7741e0..77b704b6a0 100644 --- a/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java +++ b/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java @@ -1,7 +1,5 @@ package org.hibernate.cache.access; -import java.util.Comparator; - import org.hibernate.cache.CacheException; import org.hibernate.cache.CollectionRegion; @@ -148,9 +146,4 @@ public interface CollectionRegionAccessStrategy { * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region} */ public void evictAll() throws CacheException; - - /** - * Clean up all resources. - */ - public void destroy(); } diff --git a/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java b/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java index 8f268191a8..62d8e23d4c 100644 --- a/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java +++ b/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java @@ -203,9 +203,4 @@ public interface EntityRegionAccessStrategy { * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region} */ public void evictAll() throws CacheException; - - /** - * Clean up all resources. - */ - public void destroy(); } diff --git a/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java b/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java index 0d79e3e4fa..e92db67c45 100644 --- a/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java +++ b/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java @@ -772,7 +772,7 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI while ( iter.hasNext() ) { EntityPersister p = (EntityPersister) iter.next(); if ( p.hasCache() ) { - p.getCacheAccessStrategy().destroy(); + p.getCacheAccessStrategy().getRegion().destroy(); } } @@ -780,7 +780,7 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI while ( iter.hasNext() ) { CollectionPersister p = (CollectionPersister) iter.next(); if ( p.hasCache() ) { - p.getCacheAccessStrategy().destroy(); + p.getCacheAccessStrategy().getRegion().destroy(); } }