[hibernate-commits] Hibernate SVN: r14101 - in
core/trunk/cache-jbosscache2: src/main and 29 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Thu Oct 18 16:08:50 EDT 2007
Author: bstansberry at jboss.com
Date: 2007-10-18 16:08:50 -0400 (Thu, 18 Oct 2007)
New Revision: 14101
Added:
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiMultiplexedJBossCacheRegionFactory.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiSharedJBossCacheRegionFactory.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/MultiplexedJBossCacheRegionFactory.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/SharedJBossCacheRegionFactory.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactory.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactoryImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiMultiplexingCacheInstanceManager.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiSharedCacheInstanceManager.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/SharedCacheInstanceManager.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/OptimisticReadOnlyAccess.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/OptimisticTransactionalAccess.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/OptimisticReadOnlyAccess.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/OptimisticTransactionalAccess.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CircumventChecksDataVersion.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/DataVersionAdapter.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/NonLockingDataVersion.java
core/trunk/cache-jbosscache2/src/main/resources/
core/trunk/cache-jbosscache2/src/main/resources/org/
core/trunk/cache-jbosscache2/src/main/resources/org/hibernate/
core/trunk/cache-jbosscache2/src/main/resources/org/hibernate/cache/
core/trunk/cache-jbosscache2/src/main/resources/org/hibernate/cache/jbc2/
core/trunk/cache-jbosscache2/src/main/resources/org/hibernate/cache/jbc2/builder/
core/trunk/cache-jbosscache2/src/main/resources/org/hibernate/cache/jbc2/builder/jbc2-configs.xml
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractEntityCollectionRegionTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractJBossCacheTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractRegionImplTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/JBossCacheComplianceTest.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/JBossCacheRegionFactoryTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/builder/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/builder/CacheInstanceManagerTestBase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/builder/MultiplexedCacheInstanceManagerTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/builder/SharedCacheInstanceManagerTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractReadOnlyAccessTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractTransactionalAccessTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/CollectionRegionImplTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/OptimisticInvalidatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/OptimisticReadOnlyExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/OptimisticReadOnlyTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/OptimisticReplicatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/OptimisticTransactionalExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/PessimisticInvalidatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/PessimisticReadOnlyExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/PessimisticReadOnlyTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/PessimisticReplicatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/PessimisticTransactionalExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractReadOnlyAccessTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractTransactionalAccessTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/EntityRegionImplTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/OptimisticInvalidatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/OptimisticReadOnlyExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/OptimisticReadOnlyTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/OptimisticReplicatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/OptimisticTransactionalExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/PessimisticInvalidatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/PessimisticReadOnlyExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/PessimisticReadOnlyTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/PessimisticReplicatedTransactionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/PessimisticTransactionalExtraAPITestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/AbstractEntityCacheFunctionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/AbstractQueryCacheFunctionalTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/CacheTestCaseBase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/Item.hbm.xml
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/Item.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/OptimisticJBossCacheTestDisabled.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/PessimisticJBossCacheTestDisabled.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/VersionedItem.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/optimistic-treecache.xml
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/pessimistic-treecache.xml
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/query/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/query/QueryRegionImplTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/timestamp/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/timestamp/TimestampsRegionImplTestCase.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/tm/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/tm/DummyConnectionProvider.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/tm/DummyTransaction.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/tm/DummyTransactionManager.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/tm/DummyTransactionManagerLookup.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/tm/jbc2/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/tm/jbc2/BatchModeTransactionManagerLookup.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/util/
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/util/CacheTestSupport.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/util/CacheTestUtil.java
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/util/optimistic-local-cache.xml
core/trunk/cache-jbosscache2/src/test/java/org/hibernate/test/util/pessimistic-local-cache.xml
core/trunk/cache-jbosscache2/src/test/resources/hibernate.cfg.xml
core/trunk/cache-jbosscache2/src/test/resources/hibernate.properties
core/trunk/cache-jbosscache2/src/test/resources/log4j.properties
core/trunk/cache-jbosscache2/src/test/resources/treecache.xml
Removed:
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheModeHelper.java
Modified:
core/trunk/cache-jbosscache2/
core/trunk/cache-jbosscache2/pom.xml
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/TransactionalDataRegionAdapter.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/ReadOnlyAccess.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/TransactionalAccess.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/ReadOnlyAccess.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/TransactionalAccess.java
Log:
[HHH-2555] Reimplement Hibernate/JBC 2.0 integration
Property changes on: core/trunk/cache-jbosscache2
___________________________________________________________________
Name: svn:ignore
- target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
+ target
local
*.ipr
*.iws
*.iml
.classpath
.project
.nbattrs
*.log
*.properties
.clover
.settings
bin
Modified: core/trunk/cache-jbosscache2/pom.xml
===================================================================
--- core/trunk/cache-jbosscache2/pom.xml 2007-10-18 19:49:17 UTC (rev 14100)
+++ core/trunk/cache-jbosscache2/pom.xml 2007-10-18 20:08:50 UTC (rev 14101)
@@ -25,16 +25,36 @@
<version>${version}</version>
</dependency>
<dependency>
- <groupId>jboss</groupId>
- <artifactId>jboss-cache</artifactId>
+ <groupId>${groupId}</groupId>
+ <artifactId>hibernate-testing</artifactId>
+ <version>${version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.cache</groupId>
+ <artifactId>jbosscache-core</artifactId>
<!-- I'd prefer this, at least until we get a GA...
<version>[2.0.0.BETA2,)</version>
-->
- <version>2.0.0.BETA2</version>
- </dependency>
+ <version>2.1.0.BETA1</version>
+ </dependency>
+ <!-- test dependencies -->
</dependencies>
- <build>
+ <build>
+ <testResources>
+ <testResource>
+ <filtering>false</filtering>
+ <directory>src/test/java</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </testResource>
+ <testResource>
+ <filtering>true</filtering>
+ <directory>src/test/resources</directory>
+ </testResource>
+ </testResources>
+
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -43,8 +63,72 @@
<source>1.5</source>
<target>1.5</target>
</configuration>
- </plugin>
+ </plugin>
+ <plugin>
+ <groupId>org.jboss.maven.plugins</groupId>
+ <artifactId>maven-test-ext-plugin</artifactId>
+ <version>1.1.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>extend</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>hibernate.test.validatefailureexpected</name>
+ <value>true</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
</plugins>
- </build>
+ </build>
+
+ <profiles>
+ <!-- HSQLDB is the default (eventually move to H2) -->
+ <profile>
+ <id>hsqldb</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>1.8.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.2</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>2.1_3</version>
+ </dependency>
+ </dependencies>
+ <properties>
+ <db.dialect>org.hibernate.dialect.HSQLDialect</db.dialect>
+ <jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
+ <jdbc.url>jdbc:hsqldb:target/test/db/hsqldb/hibernate</jdbc.url>
+ <jdbc.user>sa</jdbc.user>
+ <jdbc.pass/>
+ <jdbc.isolation/>
+ </properties>
+ </profile>
+ </profiles>
</project>
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java 2007-10-18 19:49:17 UTC (rev 14100)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -19,128 +19,307 @@
import java.util.Map;
import java.util.Set;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Option;
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeCreated;
+import org.jboss.cache.notifications.event.NodeCreatedEvent;
+import org.jboss.cache.optimistic.DataVersion;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.Region;
+import org.hibernate.cache.jbc2.util.CacheHelper;
+import org.hibernate.cache.jbc2.util.NonLockingDataVersion;
/**
- * General support for writing {@link Region} implementations for
- *
- *
+ * General support for writing {@link Region} implementations for JBoss Cache
+ * 2.x.
+ *
+ *
* @author Steve Ebersole
*/
+ at CacheListener
public abstract class BasicRegionAdapter implements Region {
- public static final String ITEM = "item";
+ public static final String ITEM = CacheHelper.ITEM;
- protected final Cache jbcCache;
- protected final String regionName;
- protected final Fqn regionFqn;
+ protected final Cache jbcCache;
+ protected final String regionName;
+ protected final Fqn regionFqn;
+ protected final boolean optimistic;
+
+ protected final TransactionManager transactionManager;
- public BasicRegionAdapter(Cache jbcCache, String regionName) {
- this.jbcCache = jbcCache;
- this.regionName = regionName;
- this.regionFqn = Fqn.fromString( regionName.replace( '.', '/' ) );
- activateLocalClusterNode();
- }
+ protected SetResidentListener listener;
+
+ public BasicRegionAdapter(Cache jbcCache, String regionName, String regionPrefix) {
+ this.jbcCache = jbcCache;
+ this.transactionManager = jbcCache.getConfiguration().getRuntimeConfig().getTransactionManager();
+ this.regionName = regionName;
+ this.regionFqn = createRegionFqn(regionName, regionPrefix);
+ optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
+ 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();
- }
+ protected abstract Fqn<String> createRegionFqn(String regionName, String regionPrefix);
- public String getName() {
- return regionName;
- }
+ protected void activateLocalClusterNode() {
+ try {
+ Configuration cfg = jbcCache.getConfiguration();
+ if (cfg.isUseRegionBasedMarshalling()) {
+ org.jboss.cache.Region jbcRegion = jbcCache.getRegion(regionFqn, true);
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader == null) {
+ classLoader = getClass().getClassLoader();
+ }
+ jbcRegion.registerContextClassLoader(classLoader);
+ if (jbcRegion.isActive() == false) {
+ jbcRegion.activate();
+ }
+ }
+
+ // If we are using replication, we may remove the root node
+ // and then need to re-add it. In that case, the fact
+ // that it is resident will not replicate, so use a listener
+ // to set it as resident
+ if (CacheHelper.isClusteredReplication(cfg.getCacheMode())) {
+ listener = new SetResidentListener();
+ jbcCache.addCacheListener(listener);
+ }
+
+ // Make sure the root node for the region exists and
+ // has a DataVersion that never complains
+ Node regionRoot = jbcCache.getRoot().getChild( regionFqn );
+ if (regionRoot == null) {
+ // Establish the region root node with a non-locking data version
+ DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
+ regionRoot = CacheHelper.addNode(jbcCache, regionFqn, true, true, version);
+ }
+ else if (optimistic && regionRoot instanceof NodeSPI) {
+ // FIXME Hacky workaround to JBCACHE-1202
+ if ((((NodeSPI) regionRoot).getVersion() instanceof NonLockingDataVersion) == false) {
+ ((NodeSPI) regionRoot).setVersion(NonLockingDataVersion.INSTANCE);
+ }
+ }
+ // Never evict this node
+ regionRoot.setResident(true);
+ }
+ catch (Exception e) {
+ throw new CacheException(e.getMessage(), e);
+ }
+ }
- public Cache getCacheInstance() {
- return jbcCache;
- }
+ public String getName() {
+ return regionName;
+ }
- public Fqn getRegionFqn() {
- return regionFqn;
- }
+ public Cache getCacheInstance() {
+ return jbcCache;
+ }
- 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 );
- }
- }
+ public Fqn getRegionFqn() {
+ return regionFqn;
+ }
- private void deactivateLocalNode() {
- org.jboss.cache.Region jbcRegion = jbcCache.getRegion( regionFqn, false );
- if ( jbcRegion != null && jbcRegion.isActive() ) {
- jbcRegion.deactivate();
- jbcRegion.unregisterContextClassLoader();
- }
- }
+ 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);
+ if (optimistic) {
+ option.setDataVersion(NonLockingDataVersion.INSTANCE);
+ }
+ jbcCache.getInvocationContext().setOptionOverrides(option);
+ jbcCache.removeNode(regionFqn);
+ deactivateLocalNode();
+ } catch (Exception e) {
+ throw new CacheException(e);
+ }
+ finally {
+ if (listener != null)
+ jbcCache.removeCacheListener(listener);
+ }
+ }
- public long getSizeInMemory() {
- // not supported
- return -1;
- }
+ protected void deactivateLocalNode() {
+ org.jboss.cache.Region jbcRegion = jbcCache.getRegion(regionFqn, false);
+ if (jbcRegion != null && jbcRegion.isActive()) {
+ jbcRegion.deactivate();
+ jbcRegion.unregisterContextClassLoader();
+ }
+ }
- 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 getSizeInMemory() {
+ // not supported
+ return -1;
+ }
- public long getElementCountOnDisk() {
- return -1;
- }
+ public long getElementCountInMemory() {
+ try {
+ Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
+ return childrenNames.size();
+ } catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
- 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 getElementCountOnDisk() {
+ return -1;
+ }
- public long nextTimestamp() {
- return System.currentTimeMillis() / 100;
- }
+ public Map toMap() {
+ try {
+ Map result = new HashMap();
+ Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
+ for (Object childName : childrenNames) {
+ result.put(childName, jbcCache.get(new Fqn(regionFqn, childName), ITEM));
+ }
+ return result;
+ } catch (Exception e) {
+ throw new CacheException(e);
+ }
+ }
- public int getTimeout() {
- return 600; //60 seconds
- }
+ public long nextTimestamp() {
+ return System.currentTimeMillis() / 100;
+ }
+
+ public int getTimeout() {
+ return 600; // 60 seconds
+ }
+
+ /**
+ * Performs a JBoss Cache <code>get(Fqn, Object)</code> after first
+ * {@link #suspend suspending any ongoing transaction}. Wraps any exception
+ * in a {@link CacheException}. Ensures any ongoing transaction is resumed.
+ *
+ * @param key
+ * @param opt any option to add to the get invocation. May be <code>null</code>
+ * @param suppressTimeout should any TimeoutException be suppressed?
+ * @return
+ */
+ protected Object suspendAndGet(Object key, Option opt, boolean suppressTimeout) throws CacheException {
+ Transaction tx = suspend();
+ try {
+ CacheHelper.setInvocationOption(getCacheInstance(), opt);
+ if (suppressTimeout)
+ return CacheHelper.getAllowingTimeout(getCacheInstance(), getRegionFqn(), key);
+ else
+ return CacheHelper.get(getCacheInstance(), getRegionFqn(), key);
+ } finally {
+ resume(tx);
+ }
+ }
+
+ /**
+ * Tell the TransactionManager to suspend any ongoing transaction.
+ *
+ * @return the transaction that was suspended, or <code>null</code> if
+ * there wasn't one
+ */
+ protected 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;
+ }
+
+ /**
+ * Tell the TransactionManager to resume the given transaction
+ *
+ * @param tx
+ * the transaction to suspend. May be <code>null</code>.
+ */
+ protected void resume(Transaction tx) {
+ try {
+ if (tx != null)
+ transactionManager.resume(tx);
+ } catch (Exception e) {
+ throw new CacheException("Could not resume transaction", e);
+ }
+ }
+
+ /**
+ * Get an Option with a {@link Option#getDataVersion() data version}
+ * of {@link NonLockingDataVersion}. The data version will not be
+ * set if the cache is not configured for optimistic locking.
+ *
+ * @param allowNullReturn If <code>true</code>, return <code>null</code>
+ * if the cache is not using optimistic locking.
+ * If <code>false</code>, return a default
+ * {@link Option}.
+ *
+ * @return the Option, or <code>null</code>.
+ */
+ protected Option getNonLockingDataVersionOption(boolean allowNullReturn) {
+ return optimistic ? NonLockingDataVersion.getInvocationOption()
+ : (allowNullReturn) ? null : new Option();
+ }
+
+ public static Fqn<String> getTypeFirstRegionFqn(String regionName, String regionPrefix, String regionType) {
+ Fqn<String> base = Fqn.fromString(regionType);
+ Fqn<String> added = Fqn.fromString(escapeRegionName(regionName, regionPrefix));
+ return new Fqn<String>(base, added);
+ }
+
+ public static Fqn<String> getTypeLastRegionFqn(String regionName, String regionPrefix, String regionType) {
+ Fqn<String> base = Fqn.fromString(escapeRegionName(regionName, regionPrefix));
+ return new Fqn<String>(base, regionType);
+ }
+
+ public static String escapeRegionName(String regionName, String regionPrefix) {
+ String escaped = null;
+ int idx = -1;
+ if (regionPrefix != null) {
+ idx = regionName.indexOf(regionPrefix);
+ }
+
+ if (idx > -1) {
+ int regionEnd = idx + regionPrefix.length();
+ String prefix = regionName.substring(0, regionEnd);
+ String suffix = regionName.substring(regionEnd);
+ suffix = suffix.replace('.', '/');
+ escaped = prefix + suffix;
+ } else {
+ escaped = regionName.replace('.', '/');
+ if (regionPrefix != null && regionPrefix.length() > 0) {
+ escaped = regionPrefix + "/" + escaped;
+ }
+ }
+ return escaped;
+ }
+
+ @CacheListener
+ public class SetResidentListener {
+
+ @NodeCreated
+ public void nodeCreated(NodeCreatedEvent event) {
+ if (!event.isPre() && event.getFqn().equals(getRegionFqn())) {
+ Node regionRoot = jbcCache.getRoot().getChild(getRegionFqn());
+ regionRoot.setResident(true);
+ }
+ }
+
+ }
}
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java 2007-10-18 19:49:17 UTC (rev 14100)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/CacheInstanceManager.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -15,48 +15,69 @@
*/
package org.hibernate.cache.jbc2;
+import java.util.Properties;
+
+import org.hibernate.cache.CacheException;
+import org.hibernate.cfg.Settings;
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
+ * 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
+ * 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
+ * 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();
+ /**
+ * 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();
+ /**
+ * Lifecycle callback to perform any necessary initialization of the
+ * CacheInstanceManager. Called exactly once during the construction of a
+ * {@link org.hibernate.impl.SessionFactoryImpl}.
+ *
+ * @param settings
+ * The settings in effect.
+ * @param properties
+ * The defined cfg properties
+ * @throws CacheException
+ * Indicates problems starting the L2 cache impl; considered as
+ * a sign to stop {@link org.hibernate.SessionFactory} building.
+ */
+ public void start(Settings settings, Properties properties) throws CacheException;
+
+ /**
+ * Lifecycle callback to perform any necessary cleanup of the underlying
+ * CacheInstanceManager. Called exactly once during
+ * {@link org.hibernate.SessionFactory#close}.
+ */
+ public void stop();
}
Deleted: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java 2007-10-18 19:49:17 UTC (rev 14100)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -1,89 +0,0 @@
-/*
- * 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.collection.CollectionRegionImpl;
-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 new CollectionRegionImpl( cacheInstanceManager.getCollectionCacheInstance(), regionName, metadata );
- }
-
- public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
- return null;
- }
-
- public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
- return null;
- }
-
-}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,145 @@
+/*
+ * 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.JndiSharedCacheInstanceManager;
+import org.hibernate.cache.jbc2.builder.SharedCacheInstanceManager;
+import org.hibernate.cache.jbc2.collection.CollectionRegionImpl;
+import org.hibernate.cache.jbc2.entity.EntityRegionImpl;
+import org.hibernate.cache.jbc2.query.QueryResultsRegionImpl;
+import org.hibernate.cache.jbc2.timestamp.TimestampsRegionImpl;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.Settings;
+import org.hibernate.util.PropertiesHelper;
+import org.jboss.cache.DefaultCacheFactory;
+
+;
+
+/**
+ * {@link RegionFactory} that uses one or more JBoss Cache instances for
+ * caching entities, collections, queries and timestamps. How the factory
+ * obtains a reference to the needed JBoss Cache instance(s) is determined
+ * by the injected {@link CacheInstanceManager}.
+ * <p>
+ * By default uses {@link SharedCacheInstanceManager} as its
+ * {@link #getCacheInstanceManager() CacheInstanceManager}.
+ * Basically, this uses a single shared JBoss Cache for entities, collections,
+ * queries and timestamps. The JBoss Cache instance is created by the
+ * JBC {@link DefaultCacheFactory} using the resource identified by the
+ * {@link JndiSharedCacheInstanceManager#CACHE_RESOURCE_PROP}
+ * configuration property.
+ * </p>
+ * <p>
+ * Also exposes an overloaded constructor that allows injection of different
+ * <code>CacheInstanceManager</code> implementations.
+ * </p>
+ *
+ * @author Steve Ebersole
+ * @author Brian Stansberry
+ */
+public class JBossCacheRegionFactory implements RegionFactory {
+ private CacheInstanceManager cacheInstanceManager;
+
+ /**
+ * FIXME Per the RegionFactory class Javadoc, this constructor version
+ * should not be necessary.
+ *
+ * @param props
+ */
+ public JBossCacheRegionFactory(Properties props) {
+ this();
+ }
+
+ /**
+ * Create a new JBossCacheRegionFactory.
+ */
+ public JBossCacheRegionFactory() {
+ }
+
+ /**
+ * Create a new JBossCacheRegionFactory that uses the provided
+ * {@link CacheInstanceManager}.
+ *
+ * @param cacheInstanceManager
+ */
+ public JBossCacheRegionFactory(CacheInstanceManager cacheInstanceManager) {
+ this.cacheInstanceManager = cacheInstanceManager;
+ }
+
+ public CacheInstanceManager getCacheInstanceManager() {
+ return cacheInstanceManager;
+ }
+
+ public void start(Settings settings, Properties properties) throws CacheException {
+ if (cacheInstanceManager == null) {
+ cacheInstanceManager = new SharedCacheInstanceManager();
+ }
+
+ cacheInstanceManager.start(settings, properties);
+ }
+
+ public void stop() {
+ if (cacheInstanceManager != null) {
+ cacheInstanceManager.stop();
+ }
+ }
+
+ 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,
+ getRegionPrefix(properties), metadata);
+ }
+
+ public CollectionRegion buildCollectionRegion(String regionName, Properties properties,
+ CacheDataDescription metadata) throws CacheException {
+ return new CollectionRegionImpl(cacheInstanceManager.getCollectionCacheInstance(), regionName,
+ getRegionPrefix(properties), metadata);
+ }
+
+ public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
+
+ return new QueryResultsRegionImpl(cacheInstanceManager.getQueryCacheInstance(), regionName,
+ getRegionPrefix(properties), properties);
+ }
+
+ public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
+
+ return new TimestampsRegionImpl(cacheInstanceManager.getTimestampsCacheInstance(), regionName,
+ getRegionPrefix(properties), properties);
+ }
+
+ public static String getRegionPrefix(Properties properties) {
+ return PropertiesHelper.getString(Environment.CACHE_REGION_PREFIX, properties, null);
+ }
+
+}
Property changes on: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JBossCacheRegionFactory.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiMultiplexedJBossCacheRegionFactory.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiMultiplexedJBossCacheRegionFactory.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiMultiplexedJBossCacheRegionFactory.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,61 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2;
+
+import java.util.Properties;
+
+import org.hibernate.cache.jbc2.builder.JndiMultiplexingCacheInstanceManager;
+
+/**
+ * {@link JBossCacheRegionFactory} that uses
+ * {@link JndiMultiplexingCacheInstanceManager} as its
+ * {@link #getCacheInstanceManager() CacheInstanceManager}.
+ * <p>
+ * Supports separate JBoss Cache instances for entity, collection, query
+ * and timestamp caching, with the expectation that a single multiplexed
+ * JGroups channel will be shared between the caches. JBoss Cache instances
+ * are created from a factory.
+ * </p>
+ * <p>
+ * This version finds the factory in JNDI. See
+ * {@link JndiMultiplexingCacheInstanceManager} for configuration details.
+ * </p>
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class JndiMultiplexedJBossCacheRegionFactory extends JBossCacheRegionFactory {
+
+ /**
+ * FIXME Per the RegionFactory class Javadoc, this constructor version
+ * should not be necessary.
+ *
+ * @param props
+ */
+ public JndiMultiplexedJBossCacheRegionFactory(Properties props) {
+ this();
+ }
+
+ /**
+ * Create a new MultiplexedJBossCacheRegionFactory.
+ *
+ */
+ public JndiMultiplexedJBossCacheRegionFactory() {
+ super(new JndiMultiplexingCacheInstanceManager());
+ }
+
+}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiSharedJBossCacheRegionFactory.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiSharedJBossCacheRegionFactory.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/JndiSharedJBossCacheRegionFactory.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,57 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2;
+
+import java.util.Properties;
+
+import org.hibernate.cache.jbc2.builder.JndiSharedCacheInstanceManager;
+
+/**
+ * {@link JBossCacheRegionFactory} that uses
+ * {@link JndiSharedCacheInstanceManager} as its
+ * {@link #getCacheInstanceManager() CacheInstanceManager}.
+ * <p>
+ * Basically, uses a single shared JBoss Cache for entities, collections,
+ * queries and timestamps. The JBoss Cache instance is found in JNDI
+ * using the value of the {@link JndiSharedCacheInstanceManager#CACHE_RESOURCE_PROP}
+ * configuration property as the name to look up.
+ * </p>
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class JndiSharedJBossCacheRegionFactory extends JBossCacheRegionFactory {
+
+ /**
+ * FIXME Per the RegionFactory class Javadoc, this constructor version
+ * should not be necessary.
+ *
+ * @param props
+ */
+ public JndiSharedJBossCacheRegionFactory(Properties props) {
+ this();
+ }
+
+ /**
+ * Create a new MultiplexedJBossCacheRegionFactory.
+ *
+ */
+ public JndiSharedJBossCacheRegionFactory() {
+ super(new JndiSharedCacheInstanceManager());
+ }
+
+}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/MultiplexedJBossCacheRegionFactory.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/MultiplexedJBossCacheRegionFactory.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/MultiplexedJBossCacheRegionFactory.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,61 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2;
+
+import java.util.Properties;
+
+import org.hibernate.cache.jbc2.builder.MultiplexingCacheInstanceManager;
+
+/**
+ * {@link JBossCacheRegionFactory} that uses
+ * {@link MultiplexingCacheInstanceManager} as its
+ * {@link #getCacheInstanceManager() CacheInstanceManager}.
+ * <p>
+ * Supports separate JBoss Cache instances for entity, collection, query
+ * and timestamp caching, with the expectation that a single multiplexed
+ * JGroups channel will be shared between the caches. JBoss Cache instances
+ * are created from a factory.
+ * </p>
+ * <p>
+ * This version instantiates the factory itself. See
+ * {@link MultiplexingCacheInstanceManager} for configuration details.
+ * </p>
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class MultiplexedJBossCacheRegionFactory extends JBossCacheRegionFactory {
+
+ /**
+ * FIXME Per the RegionFactory class Javadoc, this constructor version
+ * should not be necessary.
+ *
+ * @param props
+ */
+ public MultiplexedJBossCacheRegionFactory(Properties props) {
+ this();
+ }
+
+ /**
+ * Create a new MultiplexedJBossCacheRegionFactory.
+ *
+ */
+ public MultiplexedJBossCacheRegionFactory() {
+ super(new MultiplexingCacheInstanceManager());
+ }
+
+}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/SharedJBossCacheRegionFactory.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/SharedJBossCacheRegionFactory.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/SharedJBossCacheRegionFactory.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,60 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2;
+
+import java.util.Properties;
+
+import org.hibernate.cache.jbc2.builder.JndiSharedCacheInstanceManager;
+import org.hibernate.cache.jbc2.builder.SharedCacheInstanceManager;
+import org.jboss.cache.DefaultCacheFactory;
+
+/**
+ * {@link JBossCacheRegionFactory} that uses
+ * {@link SharedCacheInstanceManager} as its
+ * {@link #getCacheInstanceManager() CacheInstanceManager}.
+ * <p>
+ * Basically, uses a single shared JBoss Cache for entities, collections,
+ * queries and timestamps. The JBoss Cache instance created by the
+ * JBC {@link DefaultCacheFactory} using the resource identified by the
+ * {@link JndiSharedCacheInstanceManager#CACHE_RESOURCE_PROP}
+ * configuration property.
+ * </p>
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class SharedJBossCacheRegionFactory extends JBossCacheRegionFactory {
+
+ /**
+ * FIXME Per the RegionFactory class Javadoc, this constructor version
+ * should not be necessary.
+ *
+ * @param props
+ */
+ public SharedJBossCacheRegionFactory(Properties props) {
+ this();
+ }
+
+ /**
+ * Create a new MultiplexedJBossCacheRegionFactory.
+ *
+ */
+ public SharedJBossCacheRegionFactory() {
+ super(new SharedCacheInstanceManager());
+ }
+
+}
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/TransactionalDataRegionAdapter.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/TransactionalDataRegionAdapter.java 2007-10-18 19:49:17 UTC (rev 14100)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/TransactionalDataRegionAdapter.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -15,36 +15,38 @@
*/
package org.hibernate.cache.jbc2;
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.cache.TransactionalDataRegion;
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 abstract class TransactionalDataRegionAdapter extends BasicRegionAdapter implements TransactionalDataRegion {
- public TransactionalDataRegionAdapter(Cache jbcCache, String regionName, CacheDataDescription metadata) {
- super( jbcCache, regionName );
- this.metadata = metadata;
- }
+ protected final CacheDataDescription 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;
- }
+ public TransactionalDataRegionAdapter(Cache jbcCache, String regionName, String regionPrefix,
+ CacheDataDescription metadata) {
+ super(jbcCache, regionName, regionPrefix);
+ this.metadata = metadata;
+ }
- /**
- * {@inheritDoc}
- */
- public CacheDataDescription getCacheDataDescription() {
- return metadata;
- }
+ /**
+ * Here, for JBossCache, we consider the cache to be transaction aware if
+ * the underlying cache instance has a reference to the transaction manager.
+ */
+ public boolean isTransactionAware() {
+ return transactionManager != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public CacheDataDescription getCacheDataDescription() {
+ return metadata;
+ }
+
}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,144 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2.access;
+
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.jbc2.util.CacheHelper;
+import org.hibernate.cache.jbc2.util.DataVersionAdapter;
+import org.hibernate.cache.jbc2.util.NonLockingDataVersion;
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.optimistic.DataVersion;
+
+/**
+ * Defines the strategy for transactional access to entity or collection data in
+ * an optimistic-locking JBoss Cache using its 2.x APIs.
+ * <p>
+ * The intent of this class is to encapsulate common code and serve as a
+ * delegate for {@link EntityRegionAccessStrategy} and
+ * {@link CollectionRegionAccessStrategy} implementations.
+ * </p>
+ *
+ * @author Brian Stansberry
+ * @version $Revision: 1 $
+ */
+public class OptimisticTransactionalAccessDelegate extends TransactionalAccessDelegate {
+
+ protected final CacheDataDescription dataDescription;
+
+ public OptimisticTransactionalAccessDelegate(Cache cache, Fqn regionFqn, CacheDataDescription dataDescription) {
+ super(cache, regionFqn);
+ this.dataDescription = dataDescription;
+ }
+
+ /**
+ * Overrides the
+ * {@link TransactionalAccessDelegate#evict(Object) superclass} by adding a
+ * {@link NonLockingDataVersion} to the invocation.
+ */
+ @Override
+ public void evict(Object key) throws CacheException {
+
+ Option opt = NonLockingDataVersion.getInvocationOption();
+ CacheHelper.remove(cache, regionFqn, key, opt);
+ }
+
+ /**
+ * Overrides the {@link TransactionalAccessDelegate#evictAll() superclass}
+ * by adding a {@link NonLockingDataVersion} to the invocation.
+ */
+ @Override
+ public void evictAll() throws CacheException {
+
+ evictOrRemoveAll();
+ }
+
+ /**
+ * Overrides the
+ * {@link TransactionalAccessDelegate#insert(Object, Object, Object) superclass}
+ * by adding a {@link DataVersion} to the invocation.
+ */
+ @Override
+ public boolean insert(Object key, Object value, Object version) throws CacheException {
+
+ Option opt = getDataVersionOption(version, null);
+ CacheHelper.put(cache, regionFqn, key, value, opt);
+ return true;
+ }
+
+ @Override
+ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
+ throws CacheException {
+
+ // We ignore minimalPutOverride. JBossCache putForExternalRead is
+ // already about as minimal as we can get; it will promptly return
+ // if it discovers that the node we want to write to already exists
+ Option opt = getDataVersionOption(version, version);
+ return CacheHelper.putForExternalRead(cache, regionFqn, key, value, opt);
+ }
+
+ @Override
+ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+
+ Option opt = getDataVersionOption(version, version);
+ return CacheHelper.putForExternalRead(cache, regionFqn, key, value, opt);
+ }
+
+ @Override
+ public void remove(Object key) throws CacheException {
+
+ Option opt = NonLockingDataVersion.getInvocationOption();
+ CacheHelper.remove(cache, regionFqn, key, opt);
+ }
+
+ @Override
+ public void removeAll() throws CacheException {
+
+ evictOrRemoveAll();
+ }
+
+ @Override
+ public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
+ throws CacheException {
+
+ Option opt = getDataVersionOption(currentVersion, previousVersion);
+ CacheHelper.put(cache, regionFqn, key, value, opt);
+ return true;
+ }
+
+ private Option getDataVersionOption(Object currentVersion, Object previousVersion) {
+ DataVersion dv = (dataDescription != null && dataDescription.isVersioned()) ? new DataVersionAdapter(
+ currentVersion, previousVersion, dataDescription.getVersionComparator(), dataDescription.toString())
+ : NonLockingDataVersion.INSTANCE;
+ Option opt = new Option();
+ opt.setDataVersion(dv);
+ return opt;
+ }
+
+ private void evictOrRemoveAll() {
+ Option opt = NonLockingDataVersion.getInvocationOption();
+ CacheHelper.removeAll(cache, regionFqn, opt);
+
+ // Restablish the region root node with a non-locking data version
+ CacheHelper.addNode(cache, regionFqn, false, true, NonLockingDataVersion.INSTANCE);
+ }
+
+}
Property changes on: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
___________________________________________________________________
Name: svn:executable
+ *
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,124 @@
+/*
+ * 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.access;
+
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.cache.jbc2.util.CacheHelper;
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+
+/**
+ * Defines the strategy for transactional access to entity or collection data in
+ * a pessimistic-locking JBoss Cache using its 2.x APIs.
+ * <p>
+ * The intent of this class is to encapsulate common code and serve as a
+ * delegate for {@link EntityRegionAccessStrategy} and
+ * {@link CollectionRegionAccessStrategy} implementations.
+ * </p>
+ *
+ * @author Brian Stansberry
+ */
+public class TransactionalAccessDelegate {
+
+ protected final Cache cache;
+ protected final Fqn regionFqn;
+
+ public TransactionalAccessDelegate(Cache cache, Fqn regionFqn) {
+ this.cache = cache;
+ this.regionFqn = regionFqn;
+ }
+
+ public Object get(Object key, long txTimestamp) throws CacheException {
+
+ return CacheHelper.get(cache, regionFqn, key);
+ }
+
+ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+
+ return CacheHelper.putForExternalRead(cache, regionFqn, key, value);
+ }
+
+ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
+ throws CacheException {
+
+ // We ignore minimalPutOverride. JBossCache putForExternalRead is
+ // already about as minimal as we can get; it will promptly return
+ // if it discovers that the node we want to write to already exists
+ return CacheHelper.putForExternalRead(cache, regionFqn, key, value);
+ }
+
+ 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 {
+
+ CacheHelper.put(cache, regionFqn, key, value);
+ 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 {
+
+ CacheHelper.put(cache, regionFqn, key, value);
+ 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 {
+
+ CacheHelper.remove(cache, regionFqn, key);
+ }
+
+ public void removeAll() throws CacheException {
+ evictOrRemoveAll();
+ }
+
+ public void evict(Object key) throws CacheException {
+ CacheHelper.remove(cache, regionFqn, key);
+ }
+
+ public void evictAll() throws CacheException {
+ evictOrRemoveAll();
+ }
+
+ private void evictOrRemoveAll() throws CacheException {
+ CacheHelper.removeAll(cache, regionFqn);
+ // Restore the region root node
+ CacheHelper.addNode(cache, regionFqn, false, true, null);
+ }
+}
Property changes on: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
___________________________________________________________________
Name: svn:executable
+ *
Deleted: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java 2007-10-18 19:49:17 UTC (rev 14100)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -1,112 +0,0 @@
-/*
- * 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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.jboss.cache.Cache;
-import org.jboss.cache.DefaultCacheFactory;
-
-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 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.
- * <p/>
- * 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
- */
-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 Logger log = LoggerFactory.getLogger( 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() {
- if ( CacheModeHelper.isClusteredInvalidation( cache ) ) {
- throw new CacheException( "Query cache not supported for clustered invalidation" );
- }
- return cache;
- }
-
- /**
- * {@inheritDoc}
- */
- public Cache getTimestampsCacheInstance() {
- if ( CacheModeHelper.isClusteredInvalidation( cache ) ) {
- throw new CacheException( "Query cache not supported for clustered invalidation" );
- }
- return cache;
- }
-
- /**
- * {@inheritDoc}
- */
- public void release() {
- if ( cache != null ) {
- try {
- cache.stop();
- }
- catch( Throwable t ) {
- log.warn( "Unable to stop cache instance", t );
- }
- }
- }
-}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactory.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactory.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactory.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,74 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2.builder;
+
+import java.util.Set;
+
+import org.jboss.cache.Cache;
+
+/**
+ * Factory and registry for JBoss Cache instances configured using
+ * named configurations.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1 $
+ */
+public interface JBossCacheFactory {
+
+ /**
+ * Gets all the names of all the configurations of which this object
+ * is aware.
+ *
+ * @return
+ */
+ Set getConfigurationNames();
+
+ /**
+ * Get a cache configured according to the given configuration name.
+ * <p>
+ * The caller is free to invoke the {@link Cache#create()} and
+ * {@link Cache#start()} lifecycle methods on the returned cache, but
+ * the @link Cache#stop()} and {@link Cache#destroy()} methods should not
+ * be invoked, since it is quite possible other session factories are
+ * still using the cache. Use {@link #releaseCache(String)} to notify this
+ * factory that the caller is no longer using a cache; let the factory
+ * control stopping and destroying the underlying cache.
+ * </p>
+ *
+ * @param configName the name of the configuration
+ * @param create should the cache be instantiated if it
+ * hasn't already been?
+ * @return the cache, or <code>null</code> if
+ * <code>create</code> is false and the cache hasn't
+ * been created previously.
+ *
+ * @throws IllegalArgumentException if this object is unaware of
+ * <code>configName</code>
+ * @throws Exception if there is a problem instantiating the cache
+ */
+ Cache getCache(String configName, boolean create) throws Exception;
+
+ /**
+ * Notifies the factory that the caller is no longer using the given
+ * cache. The factory may perform cleanup operations, such as
+ * stopping and destroying the cache.
+ *
+ * @param configName
+ */
+ void releaseCache(String configName);
+
+}
\ No newline at end of file
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactoryImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactoryImpl.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JBossCacheFactoryImpl.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,361 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2.builder;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.hibernate.cache.CacheException;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationException;
+import org.jboss.cache.xml.XmlHelper;
+import org.jgroups.ChannelFactory;
+import org.jgroups.JChannelFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
+
+/**
+ * A JBossCacheConfigurationFactory. This is a basic prototype of a
+ * JBCACHE-1156 solution; only in Hibernate code base for a very short
+ * period.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1 $
+ */
+public class JBossCacheFactoryImpl implements JBossCacheFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(JBossCacheFactoryImpl.class);
+
+ private static final String DOCUMENT_ROOT = "cache-configs";
+ private static final String CONFIG_ROOT = "cache-config";
+ private static final String CONFIG_NAME = "name";
+
+ private static JBossCacheFactoryImpl sharedFactory;
+ private static String sharedChannelFactoryCfg;
+
+ private XmlConfigurationParser parser;
+ private String configResource;
+ private Map configs = new HashMap();
+ private Map caches = new HashMap();
+ private Map checkouts = new HashMap();
+ private ChannelFactory channelFactory;
+ private boolean started;
+
+ public JBossCacheFactoryImpl(String configResource, ChannelFactory factory) {
+
+ parser = new XmlConfigurationParser();
+ this.configResource = configResource;
+ this.channelFactory = factory;
+ }
+
+ public static synchronized JBossCacheFactory getSharedInstance(String cacheConfigResource, String channelFactoryConfigResource) {
+
+ if (sharedFactory == null) {
+ ChannelFactory cf = new JChannelFactory();
+ try {
+ cf.setMultiplexerConfig(channelFactoryConfigResource);
+ }
+ catch (Exception e) {
+ throw new CacheException("Problem setting ChannelFactory config", e);
+ }
+ sharedFactory = new JBossCacheFactoryImpl(cacheConfigResource, cf);
+ sharedChannelFactoryCfg = channelFactoryConfigResource;
+ }
+ else {
+ // Validate that the provided resources match the existing singleton
+ if (!sharedFactory.getConfigResource().equals(cacheConfigResource)) {
+ throw new CacheException("Provided cacheConfigResource does " +
+ "not match the existing shared factory: provided = " +
+ cacheConfigResource + "; existing = " + sharedFactory.getConfigResource());
+ }
+ else if (!sharedChannelFactoryCfg.equals(channelFactoryConfigResource)) {
+ throw new IllegalStateException("Provided channelFactoryConfigResource does " +
+ "not match the existing shared factory: provided = " +
+ channelFactoryConfigResource + "; existing = " + sharedChannelFactoryCfg);
+
+ }
+ }
+
+ return sharedFactory;
+ }
+
+ public void start() {
+ if (!started) {
+ this.configs = parser.parseConfigs(configResource);
+ started = true;
+ }
+ }
+
+ public void stop() {
+ if (started) {
+ synchronized (caches) {
+ for (Iterator it = caches.entrySet().iterator(); it.hasNext(); ) {
+ Map.Entry entry = (Entry) it.next();
+ destroyCache((Cache) entry.getValue());
+ it.remove();
+ }
+ caches.clear();
+ checkouts.clear();
+ configs.clear();
+ }
+ started = false;
+ }
+ }
+
+ public String getConfigResource() {
+ return configResource;
+ }
+
+ public ChannelFactory getChannelFactory() {
+ return channelFactory;
+ }
+
+ public Set getConfigurationNames()
+ {
+ return new HashSet(configs.keySet());
+ }
+
+ public Cache getCache(String configName, boolean create) throws Exception
+ {
+ Cache cache = null;
+ synchronized (caches) {
+ cache = (Cache) caches.get(configName);
+ if (cache == null && create) {
+ Configuration config = getConfiguration(configName);
+ cache = DefaultCacheFactory.getInstance().createCache(config, false);
+ registerCache(cache, configName);
+ }
+ else if (cache != null) {
+ incrementCheckout(configName);
+ }
+ }
+
+ return cache;
+ }
+
+ private int incrementCheckout(String configName) {
+ synchronized (checkouts) {
+ Integer count = (Integer) checkouts.get(configName);
+ if (count == null)
+ count = new Integer(0);
+ Integer newVal = new Integer(count.intValue() + 1);
+ checkouts.put(configName, newVal);
+ return newVal.intValue();
+ }
+ }
+
+ private int decrementCheckout(String configName) {
+ synchronized (checkouts) {
+ Integer count = (Integer) checkouts.get(configName);
+ if (count == null || count.intValue() < 1)
+ throw new IllegalStateException("invalid count of " + count + " for " + configName);
+
+ Integer newVal = new Integer(count.intValue() - 1);
+ checkouts.put(configName, newVal);
+ return newVal.intValue();
+ }
+ }
+
+ public void registerCache(Cache cache, String configName) {
+ synchronized (caches) {
+ if (caches.containsKey(configName))
+ throw new IllegalStateException(configName + " already registered");
+ caches.put(configName, cache);
+ incrementCheckout(configName);
+ }
+ }
+
+ public void releaseCache(String configName) {
+
+ synchronized (caches) {
+ if (!caches.containsKey(configName))
+ throw new IllegalStateException(configName + " not registered");
+ if (decrementCheckout(configName) == 0) {
+ Cache cache = (Cache) caches.remove(configName);
+ destroyCache(cache);
+ }
+ }
+ }
+
+ private void destroyCache(Cache cache) {
+ if (cache.getCacheStatus() == CacheStatus.STARTED) {
+ cache.stop();
+ }
+ if (cache.getCacheStatus() != CacheStatus.DESTROYED
+ && cache.getCacheStatus() != CacheStatus.INSTANTIATED) {
+ cache.destroy();
+ }
+ }
+
+ public Configuration getConfiguration(String configName) throws Exception {
+ Element element = (Element) configs.get(configName);
+ if (element == null)
+ throw new IllegalArgumentException("unknown config " + configName);
+ Configuration config = parser.parseConfig(element);
+ if (channelFactory != null && config.getMultiplexerStack() != null) {
+ config.getRuntimeConfig().setMuxChannelFactory(channelFactory);
+ }
+ return config;
+ }
+
+ class XmlConfigurationParser extends org.jboss.cache.factories.XmlConfigurationParser {
+
+ public Map parseConfigs(String configs) {
+ InputStream is = getAsInputStreamFromClassLoader(configs);
+ if (is == null)
+ {
+ if (log.isDebugEnabled())
+ log.debug("Unable to find configuration file " + configs + " in classpath; searching for this file on the filesystem instead.");
+ try
+ {
+ is = new FileInputStream(configs);
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new ConfigurationException("Unable to find config file " + configs + " either in classpath or on the filesystem!", e);
+ }
+ }
+
+ return parseConfigs(is);
+ }
+
+ public Map parseConfigs(InputStream stream) {
+
+ // loop through all elements in XML.
+ Element root = XmlHelper.getDocumentRoot(stream);
+ NodeList list = root.getElementsByTagName(CONFIG_ROOT);
+ if (list == null || list.getLength() == 0)
+ throw new ConfigurationException("Can't find " + CONFIG_ROOT + " tag");
+
+ Map result = new HashMap();
+
+ for (int i = 0; i < list.getLength(); i++)
+ {
+ org.w3c.dom.Node node = list.item(i);
+ if (node.getNodeType() != org.w3c.dom.Node.ELEMENT_NODE)
+ {
+ continue;
+ }
+
+ Element element = (Element) node;
+ String name = element.getAttribute(CONFIG_NAME);
+ if (name == null || name.trim().length() == 0)
+ throw new ConfigurationException("Element " + element + " has no name attribute");
+
+ result.put(name.trim(), element);
+ }
+
+ return result;
+ }
+
+ public Configuration parseConfig(Element config) throws Exception {
+
+ DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();
+ Document doc = builder.newDocument();
+ Element root = doc.createElement(DOCUMENT_ROOT);
+ doc.appendChild(root);
+ Node imported = doc.importNode(config, true);
+ root.appendChild(imported);
+
+ DOMImplementation domImpl = doc.getImplementation();
+
+ DOMImplementationLS impl =
+ (DOMImplementationLS)domImpl.getFeature("LS", "3.0");
+
+ LSSerializer writer = impl.createLSSerializer();
+ LSOutput output = impl.createLSOutput();
+ output.setEncoding("UTF-8");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ output.setByteStream(baos);
+ writer.write(doc, output);
+
+ ByteArrayInputStream is = new ByteArrayInputStream(baos.toByteArray());
+ return parseStream(is);
+ }
+
+
+ @Override
+ protected Element getMBeanElement(Element root)
+ {
+ // This is following JBoss convention.
+ NodeList list = root.getElementsByTagName(CONFIG_ROOT);
+ if (list == null) throw new ConfigurationException("Can't find " + CONFIG_ROOT + " tag");
+
+ if (list.getLength() > 1) throw new ConfigurationException("Has multiple " + CONFIG_ROOT + " tag");
+
+ Node node = list.item(0);
+ Element element = null;
+ if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
+ {
+ element = (Element) node;
+ }
+ else
+ {
+ throw new ConfigurationException("Can't find " + CONFIG_ROOT + " element");
+ }
+ return element;
+ }
+
+
+ }
+
+ public static void main(String[] args)
+ {
+ try
+ {
+ JChannelFactory cf = new JChannelFactory();
+ cf.setMultiplexerConfig("stacks.xml");
+ JBossCacheFactoryImpl factory = new JBossCacheFactoryImpl("jbc2-configs.xml", cf);
+ for (Iterator iter = factory.getConfigurationNames().iterator(); iter.hasNext(); )
+ {
+ String name = (String) iter.next();
+ Cache c = factory.getCache(name, true);
+ c.start();
+ System.out.println(name + " == " + c);
+ factory.releaseCache(name);
+ System.out.println(name + " == " + c.getCacheStatus());
+ }
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace(System.out);
+ }
+ }
+}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiMultiplexingCacheInstanceManager.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiMultiplexingCacheInstanceManager.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiMultiplexingCacheInstanceManager.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,95 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2.builder;
+
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.hibernate.cache.CacheException;
+import org.hibernate.cfg.Settings;
+import org.hibernate.util.NamingHelper;
+import org.hibernate.util.PropertiesHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A {@link MultiplexingCacheInstanceManager} that finds its cache factory
+ * in JNDI rather than creating one itself.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1 $
+ */
+public class JndiMultiplexingCacheInstanceManager extends MultiplexingCacheInstanceManager {
+
+ private static final Logger log = LoggerFactory.getLogger(JndiMultiplexingCacheInstanceManager.class);
+
+ /**
+ * Specifies the JNDI name under which the {@link JBossCacheFactory} to use is bound.
+ * There is no default value -- the user must specify the property.
+ */
+ public static final String CACHE_FACTORY_RESOURCE_PROP = "hibernate.cache.region.jbc2.cachefactory";
+
+ /**
+ * Create a new JndiMultiplexingCacheInstanceManager.
+ */
+ public JndiMultiplexingCacheInstanceManager() {
+ super();
+ }
+
+ @Override
+ public void start(Settings settings, Properties properties) throws CacheException {
+
+ String name = PropertiesHelper.getString(CACHE_FACTORY_RESOURCE_PROP, properties, null);
+ if (name == null)
+ throw new CacheException("Configuration property " + CACHE_FACTORY_RESOURCE_PROP + " not set");
+
+ JBossCacheFactory cf = locateCacheFactory( name, NamingHelper.getJndiProperties( properties ) );
+ setCacheFactory( cf );
+
+ super.start(settings, properties);
+ }
+
+ private JBossCacheFactory locateCacheFactory(String jndiNamespace, Properties jndiProperties) {
+
+ Context ctx = null;
+ try {
+ ctx = new InitialContext( jndiProperties );
+ return (JBossCacheFactory) ctx.lookup( jndiNamespace );
+ }
+ catch (NamingException ne) {
+ String msg = "Unable to retreive Cache from JNDI [" + jndiNamespace + "]";
+ log.info( msg, ne );
+ throw new CacheException( msg );
+ }
+ finally {
+ if ( ctx != null ) {
+ try {
+ ctx.close();
+ }
+ catch( NamingException ne ) {
+ log.info( "Unable to release initial context", ne );
+ }
+ }
+ }
+ }
+
+
+}
Added: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiSharedCacheInstanceManager.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiSharedCacheInstanceManager.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/JndiSharedCacheInstanceManager.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,105 @@
+/*
+ * 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): Brian Stansberry
+ */
+
+package org.hibernate.cache.jbc2.builder;
+
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.hibernate.cache.CacheException;
+import org.hibernate.cfg.Settings;
+import org.hibernate.util.NamingHelper;
+import org.hibernate.util.PropertiesHelper;
+import org.jboss.cache.Cache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A {@link SharedCacheInstanceManager} that finds the shared cache in JNDI
+ * rather than instantiating one from an XML config file.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 1 $
+ */
+public class JndiSharedCacheInstanceManager extends SharedCacheInstanceManager {
+
+ private static final Logger log = LoggerFactory.getLogger(JndiSharedCacheInstanceManager.class);
+
+ /**
+ * Specifies the JNDI name under which the {@link Cache} to use is bound.
+ * <p>
+ * Note that although this configuration property has the same name as that by
+ * in {@link SharedCacheInstanceManager#CACHE_RESOURCE_PROP the superclass},
+ * the meaning here is different. Note also that in this class' usage
+ * of the property, there is no default value -- the user must specify
+ * the property.
+ */
+ public static final String CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.shared";
+
+ /**
+ * Create a new JndiSharedCacheInstanceManager.
+ *
+ */
+ public JndiSharedCacheInstanceManager() {
+ super();
+ }
+
+ @Override
+ protected Cache createSharedCache(Settings settings, Properties properties) {
+
+ String name = PropertiesHelper.getString(CACHE_RESOURCE_PROP, properties, null);
+ if (name == null)
+ throw new CacheException("Configuration property " + CACHE_RESOURCE_PROP + " not set");
+
+ return locateCache( name, NamingHelper.getJndiProperties( properties ) );
+ }
+
+ /**
+ * No-op; we don't own the cache so we shouldn't stop it.
+ */
+ @Override
+ protected void stopSharedCache(Cache cache) {
+ // no-op. We don't own the cache so we shouldn't stop it.
+ }
+
+ private Cache locateCache(String jndiNamespace, Properties jndiProperties) {
+
+ Context ctx = null;
+ try {
+ ctx = new InitialContext( jndiProperties );
+ return (Cache) ctx.lookup( jndiNamespace );
+ }
+ catch (NamingException ne) {
+ String msg = "Unable to retreive Cache from JNDI [" + jndiNamespace + "]";
+ log.info( msg, ne );
+ throw new CacheException( msg );
+ }
+ finally {
+ if ( ctx != null ) {
+ try {
+ ctx.close();
+ }
+ catch( NamingException ne ) {
+ log.info( "Unable to release initial context", ne );
+ }
+ }
+ }
+ }
+
+}
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java 2007-10-18 19:49:17 UTC (rev 14100)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/MultiplexingCacheInstanceManager.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -19,188 +19,442 @@
import javax.transaction.TransactionManager;
import org.jboss.cache.Cache;
-import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.config.Configuration;
+import org.jgroups.ChannelFactory;
+import org.jgroups.JChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.jbc2.CacheInstanceManager;
import org.hibernate.cfg.Settings;
+import org.hibernate.transaction.TransactionManagerLookup;
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
- * communication stack.
- * <p/>
- * todo : this can get simplified once JBC implemants their "configuration factory" (the stuff akin to channel factory) - http://jira.jboss.com/jira/browse/JBCACHE-1156
+ * Allows building separate {@link Cache} instances for each type of region, but
+ * supports using the JGroups multiplexer under the covers to re-use the same group
+ * communication stack. <p/> todo : replace the prototype cache factory with
+ * the equivalent JBoss Cache solution from
+ * http://jira.jboss.com/jira/browse/JBCACHE-1156
*
* @author Steve Ebersole
+ * @author Brian Stansberry
*/
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";
+ private static final Logger log = LoggerFactory.getLogger(MultiplexingCacheInstanceManager.class);
+
+ /**
+ * Classpath or filesystem resource identifying containing JBoss Cache
+ * configurations the factory should use.
+ *
+ * @see #DEF_CACHE_FACTORY_RESOURCE
+ */
+ public static final String CACHE_FACTORY_RESOURCE_PROP = "hibernate.cache.region.jbc2.configs";
+ /**
+ * Classpath or filesystem resource identifying containing JGroups protocol
+ * stack configurations the <code>org.jgroups.ChannelFactory</code>
+ * should use.
+ *
+ * @see #DEF_MULTIPLEXER_RESOURCE
+ */
+ public static final String CHANNEL_FACTORY_RESOURCE_PROP = "hibernate.cache.region.jbc2.multiplexer.stacks";
+
+ /**
+ * Name of the configuration that should be used for entity caches.
+ *
+ * @see #DEF_ENTITY_RESOURCE
+ */
+ public static final String ENTITY_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.entity";
+ /**
+ * Name of the configuration that should be used for collection caches.
+ * No default value, as by default we try to use the same JBoss Cache
+ * instance we use for entity caching.
+ *
+ * @see #ENTITY_CACHE_RESOURCE_PROP
+ * @see #DEF_ENTITY_RESOURCE
+ */
+ public static final String COLLECTION_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.collection";
+ /**
+ * Name of the configuration that should be used for timestamp caches.
+ *
+ * @see #DEF_TS_RESOURCE
+ */
+ public static final String TIMESTAMP_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.ts";
+ /**
+ * Name of the configuration that should be used for query caches.
+ *
+ * @see #DEF_QUERY_RESOURCE
+ */
+ public static final String QUERY_CACHE_RESOURCE_PROP = "hibernate.cache.region.jbc2.cfg.query";
- public static final String OPTIMISTIC_LOCKING_SCHEME = "OPTIMISTIC";
+ /**
+ * Default value for {@link #CACHE_FACTORY_RESOURCE_PROP}. Specifies
+ * the "jbc2-configs.xml" file in this package.
+ */
+ public static final String DEF_CACHE_FACTORY_RESOURCE = "org/hibernate/cache/jbc2/builder/jbc2-configs.xml";
+ /**
+ * Default value for {@link #CHANNEL_FACTORY_RESOURCE_PROP}. Specifies
+ * "stacks.xml", which can be found in the root of the JGroups jar file.
+ * Thus, leaving this value at default means using the default protocol
+ * stack configs provided by JGroups.
+ */
+ public static final String DEF_MULTIPLEXER_RESOURCE = "stacks.xml";
+ /**
+ * Default value for {@link #ENTITY_CACHE_RESOURCE_PROP}.
+ */
+ public static final String DEF_ENTITY_RESOURCE = "optimistic-entity";
+ /**
+ * Default value for {@link #TIMESTAMP_CACHE_RESOURCE_PROP}.
+ */
+ public static final String DEF_TS_RESOURCE = "timestamps-cache";
+ /**
+ * Default value for {@link #ENTITY_CACHE_RESOURCE_PROP}.
+ */
+ public static final String DEF_QUERY_RESOURCE = "local-query";
- private static final Logger log = LoggerFactory.getLogger( MultiplexingCacheInstanceManager.class );
+ /** Cache for entities */
+ private Cache jbcEntityCache;
+ /** Cache for collections */
+ private Cache jbcCollectionCache;
+ /** Cache for timestamps */
+ private Cache jbcTsCache;
+ /** Cache for queries */
+ private Cache jbcQueryCache;
+ /** Name of config used for entities. */
+ private String entityConfig = null;
+ /** Name of config used for collections. */
+ private String collectionConfig = null;
+ /** Name of config used for queries. */
+ private String queryConfig = null;
+ /** Name of config used for timestamps. */
+ private String tsConfig = null;
+
+ /** Our cache factory */
+ private JBossCacheFactory jbcFactory;
+ /** Our channel factory */
+ private ChannelFactory channelFactory;
+ /**
+ * Did we create the factory ourself and thus can assume we are not
+ * sharing it (and the caches) with other users?
+ */
+ private boolean selfCreatedFactory;
- private final Cache jbcEntityCache;
- private final Cache jbcCollectionCache;
- private final Cache jbcTsCache;
- private final Cache jbcQueryCache;
+ /**
+ * Create a new MultiplexingCacheInstanceManager.
+ */
+ public MultiplexingCacheInstanceManager() {
+ }
+
+ /**
+ * Create a new MultiplexingCacheInstanceManager using the provided
+ * {@link Cache}s.
+ * <p>
+ * If this constructor is used, the {@link #start(Settings, Properties)}
+ * method will make no attempt to create a cache factory or obtain caches
+ * from it. Only the <code>Cache</code>s passed as arguments to this
+ * constructor will be available.
+ * </p>
+ *
+ */
+ public MultiplexingCacheInstanceManager(Cache jbcEntityCache, Cache jbcCollectionCache,
+ Cache jbcTsCache, Cache jbcQueryCache) {
+
+ this.jbcEntityCache = jbcEntityCache;
+ this.jbcCollectionCache = jbcCollectionCache;
+ this.jbcTsCache = jbcTsCache;
+ this.jbcQueryCache = jbcQueryCache;
+ }
+
+ /**
+ * Gets the cache factory.
+ */
+ public JBossCacheFactory getCacheFactory() {
+ return jbcFactory;
+ }
- 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 );
- }
- }
+ /**
+ * Sets the cache factory.
+ * @param cacheFactory the cache factory
+ */
+ public void setCacheFactory(JBossCacheFactory factory) {
+ this.jbcFactory = factory;
+ }
+
+ /**
+ * Gets the channel factory.
+ */
+ public ChannelFactory getChannelFactory() {
+ return channelFactory;
+ }
+
+ /**
+ * Set the channel factory.
+ *
+ * @param factory the channel factory
+ */
+ public void setChannelFactory(ChannelFactory factory) {
+ this.channelFactory = factory;
+ }
- public MultiplexingCacheInstanceManager(Cache jbcEntityCache, Cache jbcCollectionCache, Cache jbcTsCache, Cache jbcQueryCache) {
- this.jbcEntityCache = jbcEntityCache;
- this.jbcCollectionCache = jbcCollectionCache;
- this.jbcTsCache = jbcTsCache;
- this.jbcQueryCache = jbcQueryCache;
- }
+ /**
+ * {@inheritDoc}
+ */
+ public Cache getEntityCacheInstance() {
+ return jbcEntityCache;
+ }
- 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 );
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ public Cache getCollectionCacheInstance() {
+ return jbcCollectionCache;
+ }
- 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 );
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ public Cache getQueryCacheInstance() {
+ return jbcQueryCache;
+ }
- 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 );
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ public Cache getTimestampsCacheInstance() {
+ return jbcTsCache;
+ }
- 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 void start(Settings settings, Properties properties) throws CacheException {
+ try {
+ // We need our tm, so get it now and avoid doing other work
+ // if there is a problem
+ TransactionManagerLookup tml = settings.getTransactionManagerLookup();
+ TransactionManager tm = (tml == null ? null : tml.getTransactionManager(properties));
- /**
- * {@inheritDoc}
- */
- public Cache getEntityCacheInstance() {
- return jbcEntityCache;
- }
+ // We only build caches if *none* were passed in. Passing in
+ // caches counts as a clear statement of exactly what is wanted
+ boolean buildCaches = jbcEntityCache == null
+ && jbcCollectionCache == null
+ && jbcTsCache == null
+ && jbcQueryCache == null;
+
+ // Set up the cache factory
+ if (buildCaches && jbcFactory == null) {
+ // See if the user configured a multiplexer stack
+ if (channelFactory == null) {
+ String muxStacks = PropertiesHelper.getString(CHANNEL_FACTORY_RESOURCE_PROP, properties, DEF_MULTIPLEXER_RESOURCE);
+ if (muxStacks != null) {
+ channelFactory = new JChannelFactory();
+ channelFactory.setMultiplexerConfig(muxStacks);
+ }
+ }
+
+ String factoryRes = PropertiesHelper.getString(CACHE_FACTORY_RESOURCE_PROP, properties, DEF_CACHE_FACTORY_RESOURCE);
+ // FIXME use an impl from JBossCache
+ jbcFactory = new JBossCacheFactoryImpl(factoryRes, channelFactory);
+ ((JBossCacheFactoryImpl) jbcFactory).start();
+ selfCreatedFactory = true;
+ }
+
+ if (settings.isSecondLevelCacheEnabled()) {
- /**
- * {@inheritDoc}
- */
- public Cache getCollectionCacheInstance() {
- return jbcCollectionCache;
- }
+ if (buildCaches) {
+ entityConfig = PropertiesHelper
+ .getString(ENTITY_CACHE_RESOURCE_PROP, properties, DEF_ENTITY_RESOURCE);
+ jbcEntityCache = jbcFactory.getCache(entityConfig, true);
+
+ // Default to collections sharing entity cache if there is one
+ collectionConfig = PropertiesHelper.getString(COLLECTION_CACHE_RESOURCE_PROP, properties, entityConfig);
+ if (entityConfig.equals(collectionConfig)) {
+ jbcCollectionCache = jbcEntityCache;
+ }
+ else {
+ jbcCollectionCache = jbcFactory.getCache(collectionConfig, true);
+ }
+ }
+
+ if (jbcEntityCache != null) {
+ configureTransactionManager(jbcEntityCache, tm, false);
+ jbcEntityCache.start();
+ }
+ if (jbcCollectionCache != null) {
+ configureTransactionManager(jbcCollectionCache, tm, false);
+ jbcCollectionCache.start();
+ }
+
+ }
+ else {
+ jbcEntityCache = null;
+ jbcCollectionCache = null;
+ }
- /**
- * {@inheritDoc}
- */
- public Cache getQueryCacheInstance() {
- return jbcQueryCache;
- }
+ if (settings.isQueryCacheEnabled()) {
- /**
- * {@inheritDoc}
- */
- public Cache getTimestampsCacheInstance() {
- return jbcTsCache;
- }
+ if (buildCaches) {
+ // Default to sharing the entity cache if there is one
+ String dfltQueryResource = (entityConfig == null ? DEF_QUERY_RESOURCE : entityConfig);
+ queryConfig = PropertiesHelper.getString(QUERY_CACHE_RESOURCE_PROP, properties, dfltQueryResource);
+ if (queryConfig.equals(entityConfig)) {
+ jbcQueryCache = jbcEntityCache;
+ } else if (queryConfig.equals(collectionConfig)) {
+ jbcQueryCache = jbcCollectionCache;
+ } else {
+ jbcQueryCache = jbcFactory.getCache(queryConfig, true);
+ }
+
+ // For Timestamps, we default to a separate config
+ tsConfig = PropertiesHelper.getString(TIMESTAMP_CACHE_RESOURCE_PROP, properties, DEF_TS_RESOURCE);
+ if (tsConfig.equals(queryConfig)) {
+ jbcTsCache = jbcQueryCache;
+ }
+ else if (tsConfig.equals(entityConfig)) {
+ jbcTsCache = jbcEntityCache;
+ }
+ else if (tsConfig.equals(collectionConfig)) {
+ jbcTsCache = jbcCollectionCache;
+ }
+ else {
+ jbcTsCache = jbcFactory.getCache(tsConfig, true);
+ }
+ }
+
+ if (jbcQueryCache != null) {
+ configureTransactionManager(jbcQueryCache, tm, false);
+ jbcQueryCache.start();
+ }
+ if (jbcTsCache != null) {
+ configureTransactionManager(jbcTsCache, tm, true);
+ jbcTsCache.start();
+ }
+ }
+ else {
+ jbcTsCache = null;
+ jbcQueryCache = null;
+ }
+ }
+ catch (CacheException ce) {
+ throw ce;
+ }
+ catch (Throwable t) {
+ throw new CacheException("Unable to start region factory", t);
+ }
+ }
- /**
- * {@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 );
- }
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void stop() {
+ releaseCaches();
+ if (selfCreatedFactory) {
+ ((JBossCacheFactoryImpl) jbcFactory).stop();
+ }
+ }
+
+ /**
+ * Injects the given TransactionManager into the cache.
+ *
+ * @param cache the cache. cannot be <code>null</code>
+ * @param tm the transaction manager Hibernate recognizes
+ * May be <code>null</code>
+ * @param allowNull whether we accept a null transaction manager in the cache
+ * if <code>tm</code> is not <code>null</code>
+ *
+ * @throws CacheException if <code>cache</code> is already started and is
+ * configured with a different TransactionManager
+ * than the one we would inject
+ */
+ private void configureTransactionManager(Cache cache, TransactionManager tm, boolean allowNull) {
+ Configuration cacheConfig = cache.getConfiguration();
+ TransactionManager cacheTm = cacheConfig.getRuntimeConfig().getTransactionManager();
+ if (!safeEquals(tm, cacheTm)) {
+ if (cache.getCacheStatus() != CacheStatus.INSTANTIATED) {
+ // We can't change the TM on a running cache; just check
+ // if the cache has no TM and we're OK with that
+ if (!allowNull || cacheTm != null) {
+ throw new CacheException("JBoss Cache is already started " + "with a transaction manager ("
+ + cacheTm + ") that doesn't match our own (" + tm + ")");
+ }
+ } else {
+ // Configure the cache to use our TM
+ cacheConfig.getRuntimeConfig().setTransactionManager(tm);
+ if (tm == null) {
+ // Make sure JBC doesn't look one up
+ cacheConfig.setTransactionManagerLookupClass(null);
+ }
+ }
+ }
+ }
+
+ /**
+ * Notify cache factory that we are no longer using the caches.
+ */
+ private void releaseCaches() {
+
+ // This method should be implemented assuming it's valid to
+ // do start/stop/start -- leave state appropriate for another start
+
+ if (jbcEntityCache != null && entityConfig != null) {
+ try {
+ jbcFactory.releaseCache(entityConfig);
+ jbcEntityCache = null;
+
+ // Make sure we don't re-release the same cache
+ if (entityConfig.equals(collectionConfig))
+ collectionConfig = null;
+ if (entityConfig.equals(queryConfig))
+ queryConfig = null;
+ if (entityConfig.equals(tsConfig))
+ tsConfig = null;
+ entityConfig = null;
+ } catch (Throwable t) {
+ log.info("Unable to release entity cache instance", t);
+ }
+ }
+ if (jbcCollectionCache != null && collectionConfig != null) {
+ try {
+ jbcFactory.releaseCache(collectionConfig);
+ jbcCollectionCache = null;
+
+ if (collectionConfig.equals(queryConfig))
+ queryConfig = null;
+ if (collectionConfig.equals(tsConfig))
+ tsConfig = null;
+ collectionConfig = null;
+ } catch (Throwable t) {
+ log.info("Unable to stop collection cache instance", t);
+ }
+ }
+ if (jbcQueryCache != null && queryConfig != null) {
+ try {
+ jbcFactory.releaseCache(queryConfig);
+ jbcQueryCache = null;
+
+ if (queryConfig.equals(tsConfig))
+ tsConfig = null;
+ queryConfig = null;
+ } catch (Throwable t) {
+ log.info("Unable to stop query cache instance", t);
+ }
+ }
+ if (jbcTsCache != null && tsConfig != null) {
+ try {
+ jbcFactory.releaseCache(tsConfig);
+ jbcTsCache = null;
+
+ tsConfig = null;
+ } catch (Throwable t) {
+ log.info("Unable to stop timestamp cache instance", t);
+ }
+ }
+ }
+
+ private boolean safeEquals(Object a, Object b) {
+ return (a == b || (a != null && a.equals(b)));
+ }
}
Copied: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/SharedCacheInstanceManager.java (from rev 14071, core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/InvalidationCacheInstanceManager.java)
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/SharedCacheInstanceManager.java (rev 0)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/builder/SharedCacheInstanceManager.java 2007-10-18 20:08:50 UTC (rev 14101)
@@ -0,0 +1,247 @@
+/*
+ * 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