From 667365829a658fddbde1cd8bd493bdf5e87f223c Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 24 Jul 2007 20:34:07 +0000 Subject: [PATCH] partial jbosscache2.x support git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@12811 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../cache/jbc2/BasicRegionAdapter.java | 138 ++++++++++++ .../cache/jbc2/CacheInstanceManager.java | 62 ++++++ .../cache/jbc2/JBossCacheRegionFactory.java | 88 ++++++++ .../InvalidationCacheInstanceManager.java | 103 +++++++++ .../MultiplexingCacheInstanceManager.java | 204 ++++++++++++++++++ .../cache/jbc2/entity/EntityRegionImpl.java | 78 +++++++ .../cache/jbc2/entity/ReadOnlyAccess.java | 157 ++++++++++++++ 7 files changed, 830 insertions(+) create mode 100644 cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java create mode 100644 cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java create mode 100644 cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java create mode 100644 cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java create mode 100644 cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java create mode 100644 cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java create mode 100644 cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/ReadOnlyAccess.java 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 new file mode 100644 index 0000000000..f471237f3d --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java @@ -0,0 +1,138 @@ +/* + * 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 java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.jboss.cache.Cache; +import org.jboss.cache.Fqn; +import org.jboss.cache.config.Option; + +import org.hibernate.cache.CacheException; +import org.hibernate.cache.Region; + +/** + * General support for writing {@link Region} implementations for + * + * + * @author Steve Ebersole + */ +public abstract class BasicRegionAdapter implements Region { + public static final String ITEM = "item"; + + protected final Cache jbcCache; + protected final String regionName; + protected final Fqn regionFqn; + + public BasicRegionAdapter(Cache jbcCache, String regionName) { + this.jbcCache = jbcCache; + this.regionName = regionName; + this.regionFqn = Fqn.fromString( regionName.replace( '.', '/' ) ); + activateLocalClusterNode(); + } + + private void activateLocalClusterNode() { + org.jboss.cache.Region jbcRegion = jbcCache.getRegion( regionFqn, true ); + if ( jbcRegion.isActive() ) { + return; + } + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if ( classLoader == null ) { + classLoader = getClass().getClassLoader(); + } + jbcRegion.registerContextClassLoader( classLoader ); + jbcRegion.activate(); + } + + public String getName() { + return regionName; + } + + public void destroy() throws CacheException { + try { + // NOTE : this is being used from the process of shutting down a + // SessionFactory. Specific things to consider: + // (1) this clearing of the region should not propogate to + // other nodes on the cluster (if any); this is the + // cache-mode-local option bit... + // (2) really just trying a best effort to cleanup after + // ourselves; lock failures, etc are not critical here; + // this is the fail-silently option bit... + Option option = new Option(); + option.setCacheModeLocal( true ); + option.setFailSilently( true ); + jbcCache.getInvocationContext().setOptionOverrides( option ); + jbcCache.removeNode( regionFqn ); + deactivateLocalNode(); + } + catch( Exception e ) { + throw new CacheException( e ); + } + } + + private void deactivateLocalNode() { + org.jboss.cache.Region jbcRegion = jbcCache.getRegion( regionFqn, false ); + if ( jbcRegion != null && jbcRegion.isActive() ) { + jbcRegion.deactivate(); + jbcRegion.unregisterContextClassLoader(); + } + } + + public long getSizeInMemory() { + // not supported + return -1; + } + + public long getElementCountInMemory() { + try { + Set children = jbcCache.getRoot().getChild( regionFqn ).getChildrenNames(); + return children == null ? 0 : children.size(); + } + catch ( Exception e ) { + throw new CacheException( e ); + } + } + + public long getElementCountOnDisk() { + return -1; + } + + public Map toMap() { + try { + Map result = new HashMap(); + Set childrenNames = jbcCache.getRoot().getChild( regionFqn ).getChildrenNames(); + if (childrenNames != null) { + for ( Object childName : childrenNames ) { + result.put( childName, jbcCache.get( new Fqn( regionFqn, childName ), ITEM ) ); + } + } + return result; + } + catch (Exception e) { + throw new CacheException(e); + } + } + + public long nextTimestamp() { + return System.currentTimeMillis() / 100; + } + + public int getTimeout() { + return 600; //60 seconds + } +} diff --git a/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java new file mode 100644 index 0000000000..df0d624e75 --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java @@ -0,0 +1,62 @@ +/* + * 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; + +/** + * Acts as a buffer from how instances of {@link Cache} are built/obtained. + * + * @author Steve Ebersole + */ +public interface CacheInstanceManager { + /** + * Retrieve a handle to the {@link Cache} instance to be used for storing + * entity data. + * + * @return The entity data cache instance. + */ + public Cache getEntityCacheInstance(); + + /** + * Retrieve a handle to the {@link Cache} instance to be used for storing + * collection data. + * + * @return The collection data cache instance. + */ + public Cache getCollectionCacheInstance(); + + /** + * Retrieve a handle to the {@link Cache} instance to be used for storing + * query results. + * + * @return The query result cache instance. + */ + public Cache getQueryCacheInstance(); + + /** + * Retrieve a handle to the {@link Cache} instance to be used for storing + * timestamps. + * + * @return The timestamps cache instance. + */ + public Cache getTimestampsCacheInstance(); + + /** + * Release any held resources. + */ + public void release(); +} 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 new file mode 100644 index 0000000000..65f54f94ba --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java @@ -0,0 +1,88 @@ +/* + * 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 java.util.Properties; + +import org.hibernate.cache.CacheDataDescription; +import org.hibernate.cache.CacheException; +import org.hibernate.cache.CollectionRegion; +import org.hibernate.cache.EntityRegion; +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.entity.EntityRegionImpl; +import org.hibernate.cfg.Settings; + +/** + * {@inheritDoc} + * + * @author Steve Ebersole + */ +public class JBossCacheRegionFactory implements RegionFactory { + private CacheInstanceManager cacheInstanceManager; + + public JBossCacheRegionFactory() { + } + + public JBossCacheRegionFactory(CacheInstanceManager cacheInstanceManager) { + this.cacheInstanceManager = cacheInstanceManager; + } + + public void start(Settings settings, Properties properties) throws CacheException { + if ( cacheInstanceManager == null ) { + cacheInstanceManager = new InvalidationCacheInstanceManager( settings, properties ); + } + } + + public void stop() { + if ( cacheInstanceManager != null ) { + cacheInstanceManager.release(); + } + } + + public boolean isMinimalPutsEnabledByDefault() { + return true; + } + + public long nextTimestamp() { + return System.currentTimeMillis() / 100; + } + + public EntityRegion buildEntityRegion( + String regionName, + Properties properties, + CacheDataDescription metadata) throws CacheException { + return new EntityRegionImpl( cacheInstanceManager.getEntityCacheInstance(), regionName, metadata ); + } + + public CollectionRegion buildCollectionRegion( + String regionName, + Properties properties, + CacheDataDescription metadata) throws CacheException { + return null; + } + + public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException { + return null; + } + + public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException { + return null; + } + +} 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 new file mode 100644 index 0000000000..e573d93256 --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java @@ -0,0 +1,103 @@ +/* + * 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.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.hibernate.util.PropertiesHelper; +import org.hibernate.cache.jbc2.CacheInstanceManager; +import org.hibernate.cfg.Settings; + +/** + * A {@link org.hibernate.cache.jbc2.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. + * + * @author Steve Ebersole + */ +public class InvalidationCacheInstanceManager implements CacheInstanceManager { + public static final String CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.invalidation"; + public static final String DEFAULT_CACHE_RESOURCE = "treecache.xml"; + + private static final Log log = LogFactory.getLog( InvalidationCacheInstanceManager.class ); + + private final Cache cache; + + public InvalidationCacheInstanceManager(Settings settings, Properties properties) { + String configResource = PropertiesHelper.getString( CACHE_RESOURCE_PROP, properties, DEFAULT_CACHE_RESOURCE ); + cache = DefaultCacheFactory.getInstance().createCache( configResource, false ); + if ( settings.getTransactionManagerLookup() != null ) { + TransactionManager tm = settings.getTransactionManagerLookup().getTransactionManager( properties ); + if ( tm != null ) { + cache.getConfiguration().getRuntimeConfig().setTransactionManager( tm ); + } + } + cache.start(); + } + + public InvalidationCacheInstanceManager(Cache cache) { + this.cache = cache; + } + + /** + * {@inheritDoc} + */ + public Cache getEntityCacheInstance() { + return cache; + } + + /** + * {@inheritDoc} + */ + public Cache getCollectionCacheInstance() { + return cache; + } + + /** + * {@inheritDoc} + */ + public Cache getQueryCacheInstance() { + return cache; + } + + /** + * {@inheritDoc} + */ + public Cache getTimestampsCacheInstance() { + return cache; + } + + /** + * {@inheritDoc} + */ + public void release() { + if ( cache != null ) { + try { + cache.stop(); + } + catch( Throwable t ) { + log.warn( "Unable to stop cache instance", t ); + } + } + } +} 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 new file mode 100644 index 0000000000..7c2ed787ac --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java @@ -0,0 +1,204 @@ +/* + * 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.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.hibernate.cache.CacheException; +import org.hibernate.cache.jbc2.CacheInstanceManager; +import org.hibernate.cfg.Settings; +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. + * + * @author Steve Ebersole + */ +public class MultiplexingCacheInstanceManager implements CacheInstanceManager { + public static final String ENTITY_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.entity"; + public static final String COLL_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.collection"; + public static final String TS_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.ts"; + public static final String QUERY_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.query"; + + public static final String DEF_ENTITY_RESOURCE = "entity-cache.xml"; + public static final String DEF_COLL_RESOURCE = "collection-cache.xml"; + public static final String DEF_TS_RESOURCE = "ts-cache.xml"; + public static final String DEF_QUERY_RESOURCE = "query-cache.xml"; + + public static final String OPTIMISTIC_LOCKING_SCHEME = "OPTIMISTIC"; + + private static final Log log = LogFactory.getLog( MultiplexingCacheInstanceManager.class ); + + private final Cache jbcEntityCache; + private final Cache jbcCollectionCache; + private final Cache jbcTsCache; + private final Cache jbcQueryCache; + + public MultiplexingCacheInstanceManager(Settings settings, Properties properties) { + try { + TransactionManager tm = settings.getTransactionManagerLookup() == null + ? null + : settings.getTransactionManagerLookup().getTransactionManager( properties ); + if ( settings.isSecondLevelCacheEnabled() ) { + jbcEntityCache = buildEntityRegionCacheInstance( properties ); + jbcCollectionCache = buildCollectionRegionCacheInstance( properties ); + if ( tm != null ) { + jbcEntityCache.getConfiguration().getRuntimeConfig().setTransactionManager( tm ); + jbcCollectionCache.getConfiguration().getRuntimeConfig().setTransactionManager( tm ); + } + } + else { + jbcEntityCache = null; + jbcCollectionCache = null; + } + if ( settings.isQueryCacheEnabled() ) { + jbcTsCache = buildTsRegionCacheInstance( properties ); + jbcQueryCache = buildQueryRegionCacheInstance( properties ); + } + else { + jbcTsCache = null; + jbcQueryCache = null; + } + } + catch( CacheException ce ) { + throw ce; + } + catch( Throwable t ) { + throw new CacheException( "Unable to start region factory", t ); + } + } + + public MultiplexingCacheInstanceManager(Cache jbcEntityCache, Cache jbcCollectionCache, Cache jbcTsCache, Cache jbcQueryCache) { + this.jbcEntityCache = jbcEntityCache; + this.jbcCollectionCache = jbcCollectionCache; + this.jbcTsCache = jbcTsCache; + this.jbcQueryCache = jbcQueryCache; + } + + protected Cache buildEntityRegionCacheInstance(Properties properties) { + try { + String configResource = PropertiesHelper.getString( ENTITY_CACHE_RESOURCE_PROP, properties, DEF_ENTITY_RESOURCE ); + return DefaultCacheFactory.getInstance().createCache( configResource ); + } + catch( Throwable t ) { + throw new CacheException( "unable to build entity region cache instance", t ); + } + } + + protected Cache buildCollectionRegionCacheInstance(Properties properties) { + try { + String configResource = PropertiesHelper.getString( COLL_CACHE_RESOURCE_PROP, properties, DEF_COLL_RESOURCE ); + return DefaultCacheFactory.getInstance().createCache( configResource ); + } + catch( Throwable t ) { + throw new CacheException( "unable to build collection region cache instance", t ); + } + } + + protected Cache buildTsRegionCacheInstance(Properties properties) { + try { + String configResource = PropertiesHelper.getString( TS_CACHE_RESOURCE_PROP, properties, DEF_TS_RESOURCE ); + return DefaultCacheFactory.getInstance().createCache( configResource ); + } + catch( Throwable t ) { + throw new CacheException( "unable to build timestamps region cache instance", t ); + } + } + + protected Cache buildQueryRegionCacheInstance(Properties properties) { + try { + String configResource = PropertiesHelper.getString( QUERY_CACHE_RESOURCE_PROP, properties, DEF_QUERY_RESOURCE ); + return DefaultCacheFactory.getInstance().createCache( configResource ); + } + catch( Throwable t ) { + throw new CacheException( "unable to build query region cache instance", t ); + } + } + + /** + * {@inheritDoc} + */ + public Cache getEntityCacheInstance() { + return jbcEntityCache; + } + + /** + * {@inheritDoc} + */ + public Cache getCollectionCacheInstance() { + return jbcCollectionCache; + } + + /** + * {@inheritDoc} + */ + public Cache getQueryCacheInstance() { + return jbcQueryCache; + } + + /** + * {@inheritDoc} + */ + public Cache getTimestampsCacheInstance() { + return jbcTsCache; + } + + /** + * {@inheritDoc} + */ + public void release() { + if ( jbcEntityCache != null ) { + try { + jbcEntityCache.stop(); + } + catch( Throwable t ) { + log.info( "Unable to stop entity cache instance", t ); + } + } + if ( jbcCollectionCache != null ) { + try { + jbcCollectionCache.stop(); + } + catch( Throwable t ) { + log.info( "Unable to stop collection cache instance", t ); + } + } + if ( jbcTsCache != null ) { + try { + jbcTsCache.stop(); + } + catch( Throwable t ) { + log.info( "Unable to stop timestamp cache instance", t ); + } + } + if ( jbcQueryCache != null ) { + try { + jbcQueryCache.stop(); + } + catch( Throwable t ) { + log.info( "Unable to stop query cache instance", t ); + } + } + } +} 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 new file mode 100644 index 0000000000..e7734b6a7d --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java @@ -0,0 +1,78 @@ +/* + * 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.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; + + +/** + * 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 EntityRegionImpl(Cache jbcCache, String regionName, CacheDataDescription metadata) { + super( jbcCache, regionName ); + this.metadata = 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() + "]" + ); + } + 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; + } + + /** + * {@inheritDoc} + */ + public CacheDataDescription getCacheDataDescription() { + return metadata; + } + + Cache getCacheInstance() { + return jbcCache; + } + + Fqn getRegionFqn() { + return regionFqn; + } +} 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 new file mode 100644 index 0000000000..0bf69385ed --- /dev/null +++ b/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/ReadOnlyAccess.java @@ -0,0 +1,157 @@ +/* + * 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.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} + * + * @author Steve Ebersole + */ +public class ReadOnlyAccess implements EntityRegionAccessStrategy { + 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 ); + } + + public SoftLock lockItem(Object key, Object version) throws CacheException { + throw new UnsupportedOperationException( "Illegal attempt to lock (edit) read only item" ); + } + + public SoftLock lockRegion() throws CacheException { + throw new UnsupportedOperationException( "Illegal attempt to lock (edit) read only region" ); + } + + public void unlockItem(Object key, SoftLock lock) throws CacheException { + log.error( "Illegal attempt to lock (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; + } + + public boolean update( + Object key, + Object value, + Object currentVersion, + Object previousVersion) throws CacheException { + throw new UnsupportedOperationException( "Illegal attempt to lock (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 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(); + } +}