[jboss-cvs] JBossAS SVN: r70720 - in projects/ejb3/branches/cluster-dev/ejb3-cache: src/main/java/org/jboss/ejb3/cache and 14 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Mar 11 00:27:49 EDT 2008
Author: bstansberry at jboss.com
Date: 2008-03-11 00:27:49 -0400 (Tue, 11 Mar 2008)
New Revision: 70720
Added:
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheFactoryNotRegisteredException.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheItem.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactory.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheEntry.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/PassivationExpirationCoordinatorImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCacheEntry.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupIncompatibilityException.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/ObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingIntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationCoordinator.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationProcessor.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractBackingCacheEntry.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractTimerTask.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/FileObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/PassivationExpirationRunner.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/Ejb3CacheTestCaseBase.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/TransactionalCacheUnitTestCase.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/CacheType.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheConfig.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheItem.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEntity.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockIdentifiable.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockPassivationManager.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockRegistry.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransaction.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransactionManager.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockCluster.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockClusterMember.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockIntegratedObjectStoreSource.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/UnmarshallingMap.java
Removed:
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cacheable.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/IntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/ObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingIntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/grouped/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/CacheableTimestamp.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/EntryStateCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/FileObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl2.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupContainer.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupMemberImpl.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleIntegratedObjectStore.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache2.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/cache/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContainer.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContext.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/grouped/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/integrated/
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/passivation/
Modified:
projects/ejb3/branches/cluster-dev/ejb3-cache/.classpath
projects/ejb3/branches/cluster-dev/ejb3-cache/pom.xml
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/GroupedPassivatingUnitTestCase.java
projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockJBCIntegratedObjectStore.java
Log:
[EJBTHREE-1026] check into sandbox redesigned API concepts, impls, test fixtures
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/.classpath
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/.classpath 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/.classpath 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,22 +1,23 @@
<classpath>
<classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
- <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+ <classpathentry kind="src" path="src/test/java" output="target/tests-classes"/>
+ <classpathentry kind="src" path="src/test/resources" output="target/tests-classes" excluding="**/*.java"/>
<classpathentry kind="output" path="target/classes"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-logging-log4j/2.0.4.GA/jboss-common-logging-log4j-2.0.4.GA.jar"/>
+ <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-logging-spi/2.0.4.GA/jboss-common-logging-spi-2.0.4.GA.jar"/>
+ <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-core/2.0.4.GA/jboss-common-core-2.0.4.GA.jar"/>
+ <classpathentry kind="var" path="M2_REPO/apache-xerces/xml-apis/2.7.1/xml-apis-2.7.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/apache-httpclient/commons-httpclient/2.0.2/commons-httpclient-2.0.2.jar"/>
<classpathentry kind="var" path="M2_REPO/oswego-concurrent/concurrent/1.3.4/concurrent-1.3.4.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/jboss/javaee/jboss-ejb-api/3.0.0.20070913080910/jboss-ejb-api-3.0.0.20070913080910.jar"/>
- <classpathentry kind="var" path="M2_REPO/apache-xerces/xml-apis/2.7.1/xml-apis-2.7.1.jar"/>
- <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-core/2.0.4.GA/jboss-common-core-2.0.4.GA.jar"/>
- <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-logging-spi/2.0.4.GA/jboss-common-logging-spi-2.0.4.GA.jar"/>
<classpathentry kind="var" path="M2_REPO/apache-slide/webdavlib/2.0/webdavlib-2.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
<classpathentry kind="var" path="M2_REPO/jboss/jboss-serialization/1.0.3.GA/jboss-serialization-1.0.3.GA.jar"/>
- <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.4/junit-4.4.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/jboss-common-core/2.2.1.GA/jboss-common-core-2.2.1.GA.jar"/>
- <classpathentry kind="var" path="M2_REPO/org/jboss/javaee/jboss-transaction-api/1.0.1.20070913080910/jboss-transaction-api-1.0.1.20070913080910.jar"/>
- <classpathentry kind="var" path="M2_REPO/trove/trove/2.1.1/trove-2.1.1.jar"/>
- <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
- <classpathentry kind="var" path="M2_REPO/jboss/jboss-common-logging-log4j/2.0.4.GA/jboss-common-logging-log4j-2.0.4.GA.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/jboss/ejb3/jboss-ejb3-ext-api/0.3-SNAPSHOT/jboss-ejb3-ext-api-0.3-SNAPSHOT.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/jboss/javaee/jboss-ejb-api/3.0.0.Beta3Update1/jboss-ejb-api-3.0.0.Beta3Update1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/jboss/javaee/jboss-transaction-api/1.0.1.Beta3Update1/jboss-transaction-api-1.0.1.Beta3Update1.jar"/>
<classpathentry kind="var" path="M2_REPO/jboss/jbossws/jboss-jaxrpc/1.0.4.GA/jboss-jaxrpc-1.0.4.GA.jar"/>
- <classpathentry kind="var" path="M2_REPO/apache-httpclient/commons-httpclient/2.0.2/commons-httpclient-2.0.2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/trove/trove/1.0.2/trove-1.0.2.jar"/>
</classpath>
\ No newline at end of file
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/pom.xml
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/pom.xml 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/pom.xml 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,96 +1,79 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ vi:ts=2:sw=2:expandtab:
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <!-- Define Parent -->
<parent>
- <groupId>org.jboss</groupId>
- <!--
- <artifactId>jboss-ejb3</artifactId>
- <version>0.11.0-SNAPSHOT</version>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-build</artifactId>
+ <version>0.13.0-SNAPSHOT</version>
<relativePath>../build/pom.xml</relativePath>
- -->
- <artifactId>jboss-parent</artifactId>
- <version>3</version>
</parent>
+
+ <!-- Maven POM Model Version -->
<modelVersion>4.0.0</modelVersion>
- <groupId>org.jboss</groupId>
+
+ <!-- Artifact Information -->
+ <groupId>org.jboss.ejb3</groupId>
<artifactId>jboss-ejb3-cache</artifactId>
- <version>0.11-SNAPSHOT</version>
+ <version>0.14.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JBoss EJB 3.0 Cache</name>
- <url>http://www.jboss.org</url>
+ <url>http://labs.jboss.com/jbossejb3/</url>
<description>The Java EJB 3.0 Cache classes</description>
- <scm>
- <connection>scm:svn:http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/</connection>
- <developerConnection>scm:svn:https://svn.jboss.org/repos/jbossas/projects/ejb/trunk/</developerConnection>
- <url>http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/ejb3/trunk/</url>
- </scm>
- <build>
- <plugins>
- <!-- Normally defined in the parent -->
- <plugin>
- <groupId>org.jboss.maven.plugins</groupId>
- <artifactId>maven-jboss-deploy-plugin</artifactId>
- <version>1.4</version>
- <executions>
- <execution>
- <goals>
- <goal>jboss-deploy</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <jbossDeployRoot>${jboss.repository.root}</jbossDeployRoot>
- <groupId>jboss</groupId>
- </configuration>
- <inherited>true</inherited>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-release-plugin</artifactId>
- <configuration>
- <tagBase>https://svn.jboss.org/repos/jbossas/projects/ejb3/tags</tagBase>
- </configuration>
- </plugin>
- </plugins>
- </build>
+
+
<dependencies>
+
+ <!-- EJB3 API -->
<dependency>
- <groupId>org.jboss</groupId>
- <artifactId>jboss-common-core</artifactId>
- <version>2.2.1.GA</version>
+ <groupId>org.jboss.javaee</groupId>
+ <artifactId>jboss-ejb-api</artifactId>
</dependency>
+
+ <!-- EJB3 External API -->
<dependency>
- <groupId>jboss</groupId>
- <artifactId>jboss-common-logging-spi</artifactId>
- <version>2.0.4.GA</version>
+ <groupId>org.jboss.ejb3</groupId>
+ <artifactId>jboss-ejb3-ext-api</artifactId>
</dependency>
+
+ <!-- GNU Trove -->
<dependency>
- <groupId>jboss</groupId>
- <artifactId>jboss-common-logging-log4j</artifactId>
- <version>2.0.4.GA</version>
- <scope>test</scope>
+ <groupId>trove</groupId>
+ <artifactId>trove</artifactId>
+ <scope>runtime</scope>
</dependency>
+
+ <!-- JBoss Common Core -->
<dependency>
- <groupId>org.jboss.javaee</groupId>
- <artifactId>jboss-ejb-api</artifactId>
- <version>3.0.0.20070913080910</version>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-common-core</artifactId>
</dependency>
+
+ <!-- JBoss Common Logging -->
<dependency>
<groupId>jboss</groupId>
+ <artifactId>jboss-common-logging-log4j</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+ <!-- JBoss Serialization -->
+ <dependency>
+ <groupId>jboss</groupId>
<artifactId>jboss-serialization</artifactId>
- <version>1.0.3.GA</version>
</dependency>
+
+ <!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>3.8.1</version>
<scope>test</scope>
</dependency>
-
- <!-- For jboss serialization -->
- <dependency>
- <groupId>trove</groupId>
- <artifactId>trove</artifactId>
- <version>2.1.1</version>
- <scope>runtime</scope>
- </dependency>
+
</dependencies>
+
</project>
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -23,6 +23,7 @@
import javax.ejb.NoSuchEJBException;
+
/**
* Cache a stateful object and make sure any life cycle callbacks are
* called at the appropriate time.
@@ -31,19 +32,27 @@
* scope.
*
* @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @author Brian Stansberry
+ *
* @version $Revision: $
*/
-public interface Cache<T extends Identifiable>
+public interface Cache<T extends CacheItem>
{
/**
- * Create a new object.
+ * Creates and caches a new instance of <code>T</code>. The new
+ * <code>T</code> *is* returned, but is not regarded as being "in use".
+ * Callers *must not* attempt to use the new <code>T</code> without
+ * first calling {@link #get(Object)}.
*
- * @param initTypes
- * @param initValues
- * @return
+ * @param initTypes the types of any <code>initValues</code>.
+ * May be <code>null</code>.
+ * @param initValues any paramaters to pass to <code>T</code>'s constructor.
+ * May be null, in which case a default constructor will
+ * be used.
+ * @return the new <code>T</code>
*/
T create(Class<?> initTypes[], Object initValues[]);
-
+
/**
* Get the specified object from cache. This will mark
* the object as being in use.
@@ -51,26 +60,27 @@
* @param key the identifier of the object
* @return the object
* @throws NoSuchEJBException if the object does not exist
+ * @throws IllegalStateException if the object is already in use by another
+ * transaction or if {@link #finished(CacheItem)}
+ * has not been invoked since the last time
+ * the object was gotten.
*/
T get(Object key) throws NoSuchEJBException;
/**
- * Peek at an object which might be in use.
+ * Signal the finish of the current operation on the object.
+ * If the object was {@link #get(Object) gotten from the cache} in the
+ * course of an ongoing transaction, the object will still be regarded as in
+ * use, but <code>get()</code> can safely be invoked again by that same
+ * transaction. If there was no transaction in effect when the object was
+ * gotten from the cache, invoking this method marks the object as no
+ * longer being in use.
*
- * @param key the identifier of the object
- * @return the object
- * @throws NoSuchEJBException if the object does not exist
+ * @param obj object previously gotten via {@link #get(Object)}
*/
- T peek(Object key) throws NoSuchEJBException;
-
+ void finished(T obj);
+
/**
- * Release the object from use.
- *
- * @param obj the object
- */
- void release(T obj);
-
- /**
* Remove the specified object from cache.
*
* @param key the identifier of the object
@@ -78,31 +88,27 @@
void remove(Object key);
/**
- * Gets whether this cache supports clustering functionality.
+ * Gets whether this cache supports {@link SerializationGroup} management.
*
- * @return <code>true</code> if clustering is supported, <code>false</code>
- * otherwise
+ * @return <code>true</code> if group management is supported;
+ * <code>false</code> otherwise
*/
- boolean isClustered();
-
+ boolean isGroupAware();
+
/**
- * Replicate the object. The object must not be in use.
+ * Gets the group to which the given object belongs.
*
- * @param key the identifier of the object
- *
- * @throws IllegalStateException if the object, or another object in the
- * same {@link SerializationGroup} as the object,
- * is in use.
- * @throws UnsupportedOperationException if {@link #isClustered()} returns
- * <code>false</code>
+ * @param obj the object
+ * @return the group, or <code>null</code> if the object is not a member
+ * of a group
*/
- void replicate(Object key);
-
+ SerializationGroup<T> getGroup(T obj);
+
/**
* Start the cache.
*/
void start();
-
+
/**
* Stop the cache.
*/
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheFactoryNotRegisteredException.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheFactoryNotRegisteredException.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheFactoryNotRegisteredException.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache;
+
+/**
+ * Thrown when attempting to retrieve a cache factory with an
+ * unrecognized name from the {@link StatefulCacheFactoryRegistry}.
+ *
+ * @author <a href="mailto:andrew.rubinger at redhat.com">ALR</a>
+ * @version $Revision: $
+ */
+public class CacheFactoryNotRegisteredException extends Exception
+{
+
+ // Class Members
+ private static final long serialVersionUID = -881723607135494483L;
+
+ // Constructors
+
+ public CacheFactoryNotRegisteredException()
+ {
+ super();
+ }
+
+ public CacheFactoryNotRegisteredException(String message)
+ {
+ super(message);
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheItem.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheItem.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/CacheItem.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache;
+
+import java.io.Serializable;
+
+/**
+ * An item that can be stored in a {@link Cache}.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public interface CacheItem extends Identifiable, Serializable
+{
+ /**
+ * Gets whether this object's internal state has been modified since
+ * the last request to this method.
+ * <p>
+ * Implementations must be aggressive about returning <code>true</code> if
+ * they are uncertain about whether they have been modified; <code>false</code>
+ * should only be returned if the implementing object is certain its
+ * internal state has not been modified.
+ * </p>
+ *
+ * @return <code>true</code> if the state has been modified or the
+ * implementing object does not know; <code>false</code> otherwise.
+ */
+ boolean isModified();
+}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cacheable.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cacheable.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/Cacheable.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,91 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ejb3.cache;
-
-
-/**
- * An object that can be cached.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public interface Cacheable extends Identifiable
-{
- /** Possible states of the entry. See elements for details. */
-// public static enum State {
-// /**
-// * A reference to the entry's {@link CacheEntry#getObject container object}
-// * has *not* been handed out to a caller and there is no need to
-// * invoke any @PostActivate callback before handing out a reference.
-// */
-// READY,
-// /**
-// * A reference to the entry's {@link CacheEntry#getObject container object}
-// * has been handed out to a caller and has not yet been released.
-// *
-// * @see Cache#get(Object)
-// * @see Cache#peek(Object)
-// * @see Cache#release(Identifiable)
-// */
-// IN_USE,
-// /**
-// * A reference to the entry's {@link CacheEntry#getObject container object}
-// * has *not* been handed out to a caller, but any @PostActivate callback
-// * should be invoked before handing out a reference.
-// */
-// PASSIVATED
-// };
-//
-// State getCacheState();
-//
-// void setCacheState(State state);
-
-// void setLastUsed(long lastUsed);
-
- /**
- * Gets whether this object is in use by a caller.
- */
- boolean isInUse();
-
- /**
- * Sets whether this object is in use by a caller.
- *
- * @param inUse
- */
- void setInUse(boolean inUse);
-
- /**
- * Gets the timestamp of the last time this object was in use.
- *
- * @return
- */
- long getLastUsed();
-
- /**
- * Gets whether this object's internal state has been modified since
- * the last request to this method.
- *
- * @return
- */
- boolean isModified();
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/IntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/IntegratedObjectStore.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/IntegratedObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,109 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ejb3.cache;
-
-/**
- * An in-memory store for identifiable objects that integrates a persistent store.
- * Note that this class does NOT call any callbacks.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public interface IntegratedObjectStore<T extends Cacheable>
-{
- /**
- * Put a new entry into the store. This operation should only be
- * performed once per entry.
- *
- * @param entry the object to store. Cannot be <code>null</code>.
- *
- * @throws IllegalStateException if the store is already managing an entry
- * with the same {@link Identifiable#getId() id}.
- * It is not a requirement that the store throw
- * this exception in this case, but it is
- * permissible. This basically puts the onus on
- * callers to ensure this operation is only
- * performed once per entry.
- */
- void insert(T entry);
-
- /**
- * Gets the entry with the given id from the store.
- *
- * @param key {@link Identifiable#getId() id} of the entry.
- * Cannot be <code>null</code>.
- * @return the object store under <code>id</code>. May return <code>null</code>.
- */
- T get(Object key);
-
- /**
- * Update an already cached item.
- *
- * @param entry the entry to update
- *
- * @throws IllegalStateException if the store isn't already managing an entry
- * with the same {@link Identifiable#getId() id}.
- * It is not a requirement that the store throw
- * this exception in this case, but it is
- * permissible. This basically puts the onus on
- * callers to ensure {@link #insert(Cacheable)}
- * is invoked before the first replication.
- */
- void update(T entry);
-
- /**
- * Remove the object with the given key from the store.
- *
- * @param key {@link Identifiable#getId() id} of the entry.
- * Cannot be <code>null</code>.
- *
- * @return the object that was cached under <code>key</code>
- */
- T remove(Object key);
-
- /**
- * Remove the entry with the given key from any in-memory store
- * while retaining it in the persistent store.
- *
- * @param entry the entry to passivate
- */
- void passivate(T entry);
-
- /**
- * Gets whether this store supports clustering functionality.
- *
- * @return <code>true</code> if clustering is supported, <code>false</code>
- * otherwise
- */
- boolean isClustered();
-
- /**
- * Perform any initialization work.
- */
- void start();
-
- /**
- * Perform any shutdown work.
- */
- void stop();
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/ObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/ObjectStore.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/ObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache;
-
-/**
- * Stores an indentifiable object on a persistence store. Note that the object store
- * does NOT call any callbacks.
- *
- * It is assumed the key represents something meaning full to the object store.
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision: $
- */
-public interface ObjectStore<T extends Identifiable>
-{
- /**
- * Load the object from storage.
- *
- * @param key the object identifier
- * @return the object or null if not found
- */
- T load(Object key);
-
- /**
- * Store the object into storage.
- *
- * @param obj the object
- */
- void store(T obj);
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingCache.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache;
-
-/**
- * A cache which passivates unused objects.
- *
- * A PassivatingCache is linked to an ObjectStore to store the
- * passivated object and a PassivationManager to managed lifecycle
- * callbacks on the object.
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision$
- */
-public interface PassivatingCache<T extends Identifiable> extends Cache<T>
-{
- /**
- * Force passivation of an object. The object must not be in use.
- *
- * @param key the identifier of the object
- *
- * @throws IllegalStateException if the object, or another object in the
- * same {@link SerializationGroup} as the object,
- * is in use.
- */
- void passivate(Object key);
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingIntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingIntegratedObjectStore.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingIntegratedObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,90 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ejb3.cache;
-
-/**
- * An {@link IntegratedObjectStore} that is able to use its knowledge of
- * when objects are accessed to coordinate the passivation and removal of
- * cached objects.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public interface PassivatingIntegratedObjectStore<T extends Cacheable>
- extends IntegratedObjectStore<T>
-{
- /**
- * Gets how often, in seconds, this object should process
- * {@link #runPassivation() passivations} and
- * {@link #runExpiration() expirations}.
- *
- * @return interval, in seconds, at which passivations and expirations
- * are processed. A value of less than 1 means this object will
- * not itself initiate processing, depending instead on an external
- * caller to do so.
- */
- int getInterval();
-
- /**
- * Sets how often, in seconds, this object should process
- * {@link #runPassivation() passivations} and
- * {@link #runExpiration() expirations}.
- *
- * @param seconds interval, in seconds, at which passivations and
- * expirations should be processed. A value of less than 1
- * means this object will not itself initiate processing,
- * depending instead on an external caller to do so.
- */
- void setInterval(int seconds);
-
- /**
- * Determine what cached objects need to be passivated and
- * {@link PassivatingCache#passivate(Object) tell the cache to passivate them}.
- *
- */
- void runPassivation();
-
- /**
- * Check what cached objects need to be removed and
- * {@link Cache#remove(Object) tell the cache to remove them}.
- *
- */
- void runExpiration();
-
- /**
- * Handback provided by the controlling {@link PassivatingCache} to
- * allow the actual {@link PassivatingCache#passivate(Object) passivate}
- * and {@link Cache#remove(Object) remove} calls.
- *
- * @param cache
- */
- void setPassivatingCache(PassivatingCache<T> cache);
-
- // TODO determine what the standard configurations are
-
-// int getPassivationTimeout();
-// void setPassivationTimeout(int timeout);
-//
-// int getRemovalTimeout();
-// void setRemovalTimeout(int timeout);
-}
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivationManager.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -23,13 +23,15 @@
import java.io.Serializable;
+import org.jboss.ejb3.cache.SerializationGroup;
+
/**
- * Manage passivation and replication lifecycle callbacks on an object.
+ * Manages passivation and replication lifecycle callbacks on an object.
*
* @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
* @version $Revision$
*/
-public interface PassivationManager<T extends Serializable>
+public interface PassivationManager<T extends CacheItem & Serializable>
{
/**
* This method is called after an object has been retrieved
@@ -55,21 +57,10 @@
void prePassivate(T obj);
/**
- * Gets whether this PassivationManager supports clustering functionality.
- *
- * @return <code>true</code> if clustering is supported, <code>false</code>
- * otherwise
- */
- boolean isClustered();
-
- /**
* This method is called after a previously replicated object has been
* retrieved from a clustered cache.
*
- * @param obj the object.
- *
- * @throws UnsupportedOperationException if {@link #isClustered()} returns
- * <code>false</code>
+ * @param obj the object.
*/
void postReplicate(T obj);
@@ -80,14 +71,11 @@
* @param obj the object
*
* @throws IllegalStateException if <code>obj</code>, or another object in the
- * same {@link SerializationGroup} as
+ * same {@link SerializationGroupImpl} as
* <code>obj</code>, is in use. Checking if
* an object is in use and throwing this
* exception is not required, so callers should
* not assume it will be thrown.
- *
- * @throws UnsupportedOperationException if {@link #isClustered()} returns
- * <code>false</code>
*/
void preReplicate(T obj);
}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/SerializationGroup.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache;
+
+import java.util.Iterator;
+
+/**
+ * Defines a group of cache items which must always be serialized in one
+ * unit of work.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @author Brian Stansberry
+ * @version $Revision: $
+ */
+public interface SerializationGroup<T extends CacheItem>
+ extends CacheItem
+{
+ /**
+ * Gets the number of group members.
+ */
+ int size();
+
+ /**
+ * Returns an iterator over the group members. The iterator does not
+ * support the {@link Iterator#remove()} operation.
+ *
+ * @return the iterator
+ */
+ Iterator<T> iterator();
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactory.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactory.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+
+/**
+ * Defines the contract for an EJB3 Stateful Cache Factory
+ *
+ * @author <a href="mailto:andrew.rubinger at redhat.com">ALR</a>
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public interface StatefulCacheFactory<T extends CacheItem>
+{
+ /**
+ * Creates a cache for a container.
+ *
+ * @param containerName fully qualified name of the container. Must be
+ * unique across all possibly co-existent containers
+ * in the system. Should be as concise as possible,
+ * as this name may be replicated around a cluster
+ * in numerous messages. Should not contain characters
+ * that are illegal to include in an element of a
+ * filesystem path. An example containerName
+ * for an EJBContainer might be
+ * "ear=foo.ear,jar=foo.jar,name=Bar".
+ * @param factory factory for creating objects managed by the cache
+ * @param passivationManager manager for invoking pre and post passivation
+ * and replication callbacks on the cached objects
+ * @param config configuration details for the cache
+ *
+ * @return the cache
+ */
+ Cache<T> createCache(String containerName,
+ StatefulObjectFactory<T> factory,
+ PassivationManager<T> passivationManager,
+ CacheConfig config);
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulCacheFactoryRegistry.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache;
+
+import java.util.Map;
+
+/**
+ * Registry for all configured Stateful Cache Factory implementations
+ *
+ * TODO Does this belong in ejb3-core? That would allow all of the
+ * StatefulCacheFactory<? extends CacheItem> usage to be replaced with
+ * StatefulCacheFactory<StatefulBeanContext> without leaking the
+ * StatefulBeanContext class to ejb3-cache.
+ *
+ * @author <a href="mailto:andrew.rubinger at redhat.com">ALR</a>
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class StatefulCacheFactoryRegistry<T extends CacheItem>
+{
+ // Instance Members
+ private Map<String, StatefulCacheFactory<T>> factories;
+
+ // Accessors / Mutators
+
+ public Map<String, StatefulCacheFactory<T>> getFactories()
+ {
+ return factories;
+ }
+
+ public void setFactories(Map<String, StatefulCacheFactory<T>> factories)
+ {
+ this.factories = factories;
+ }
+
+ public void addCacheFactory(String name, StatefulCacheFactory<T> factory)
+ {
+ this.factories.put(name, factory);
+ }
+
+ public void removeCacheFactory(String name)
+ {
+ this.factories.remove(name);
+ }
+
+ // Functional Methods
+
+ /**
+ * Obtains the Cache Factory with the specified registered name
+ *
+ * @param name The registered name of the cache factory to retrieve
+ * @return The Cache Factory
+ */
+ public StatefulCacheFactory<T> getCacheFactory(String name) throws CacheFactoryNotRegisteredException
+ {
+ // Obtain cache factory
+ StatefulCacheFactory<T> cacheFactory = this.factories.get(name);
+
+ // Ensure registered
+ if (cacheFactory == null)
+ {
+ throw new CacheFactoryNotRegisteredException("Cache Factory with name " + name + " is not registered.");
+ }
+
+ return cacheFactory;
+ }
+}
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/StatefulObjectFactory.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -31,7 +31,7 @@
* @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
* @version $Revision: $
*/
-public interface StatefulObjectFactory<T>
+public interface StatefulObjectFactory<T extends CacheItem>
{
/**
* Creates a new stateful object by calling it's empty constructor,
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/CacheableTimestamp.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/CacheableTimestamp.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/CacheableTimestamp.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,100 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ejb3.cache.impl;
-
-import org.jboss.ejb3.cache.Cacheable;
-import org.jboss.ejb3.cache.Identifiable;
-import org.jboss.ejb3.cache.IntegratedObjectStore;
-
-/**
- * Encapsulation of the {@link Identifiable#getId() id} and
- * {@link Cacheable#getLastUsed() last used timestamp} of
- * a cached {@link Cacheable}.
- * <p>
- * Implements <code>Comparable</code> to make it easy to sort
- * for LRU comparisons.
- * </p>
- *
- * @see IntegratedObjectStore#getInMemoryEntries()
- * @see IntegratedObjectStore#getPassivatedEntries()
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public class CacheableTimestamp
- implements Identifiable, Comparable<CacheableTimestamp>
-{
- private Object id;
- private long lastUsed;
-
- public CacheableTimestamp(Object id, long lastUsed)
- {
- assert id != null : "id cannot be null";
- assert lastUsed > 0 : "lastUsed must be positive";
-
- this.id = id;
- this.lastUsed = lastUsed;
- }
-
- public Object getId()
- {
- return id;
- }
-
- public long getLastUsed()
- {
- return lastUsed;
- }
-
- /**
- * Compares based on {@link #getLastUsed() last used}, returning
- * -1 for earlier timestamps.
- */
- public int compareTo(CacheableTimestamp o)
- {
- if (this.lastUsed < o.lastUsed)
- return -1;
- else if (this.lastUsed > o.lastUsed)
- return 1;
- return 0;
- }
-
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- return true;
-
- if (obj instanceof CacheableTimestamp)
- {
- return this.id.equals(((CacheableTimestamp) obj).id);
- }
- return false;
- }
-
- @Override
- public int hashCode()
- {
- return id.hashCode();
- }
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/EntryStateCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/EntryStateCache.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/EntryStateCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,155 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.ejb.NoSuchEJBException;
-
-import org.jboss.ejb3.cache.Cache;
-import org.jboss.ejb3.cache.Identifiable;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-
-/**
- * Comment
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision$
- */
-public class EntryStateCache<T extends Identifiable> implements Cache<T>
-{
- private StatefulObjectFactory<T> factory;
- private Map<Object, Entry> cache;
-
- private static enum State { READY, IN_USE };
-
- private class Entry
- {
- long lastUsed;
- T obj;
- State state;
-
- Entry(T obj)
- {
- assert obj != null : "obj is null";
-
- this.lastUsed = System.currentTimeMillis();
- this.obj = obj;
- this.state = State.IN_USE;
- }
- }
-
- public EntryStateCache(StatefulObjectFactory<T> factory)
- {
- assert factory != null : "factory is null";
-
- this.factory = factory;
- this.cache = new HashMap<Object, Entry>();
- }
-
- public T create(Class<?>[] initTypes, Object[] initValues)
- {
- T obj = factory.create(initTypes, initValues);
- Entry entry = new Entry(obj);
- synchronized (cache)
- {
- cache.put(obj.getId(), entry);
- }
- return obj;
- }
-
- public T get(Object key) throws NoSuchEJBException
- {
- synchronized (cache)
- {
- Entry entry = cache.get(key);
- if(entry == null)
- throw new NoSuchEJBException(String.valueOf(key));
- if(entry.state != State.READY)
- throw new IllegalStateException("entry " + entry + " is not ready");
- entry.state = State.IN_USE;
- entry.lastUsed = System.currentTimeMillis();
- return entry.obj;
- }
- }
-
- public T peek(Object key) throws NoSuchEJBException
- {
- synchronized (cache)
- {
- Entry entry = cache.get(key);
- if(entry == null)
- throw new NoSuchEJBException(String.valueOf(key));
- return entry.obj;
- }
- }
-
- public void release(T obj)
- {
- synchronized (cache)
- {
- Entry entry = cache.get(obj.getId());
- if(entry.state != State.IN_USE)
- throw new IllegalStateException("entry " + entry + " is not in use");
- entry.state = State.READY;
- entry.lastUsed = System.currentTimeMillis();
- }
- }
-
- public void remove(Object key)
- {
- Entry entry;
- synchronized (cache)
- {
- entry = cache.remove(key);
- if(entry.state != State.READY)
- throw new IllegalStateException("entry " + entry + " is not ready");
- }
- if(entry != null)
- factory.destroy(entry.obj);
- }
-
- public void start()
- {
- // TODO Auto-generated method stub
-
- }
-
- public void stop()
- {
- // TODO Auto-generated method stub
-
- }
-
- public boolean isClustered()
- {
- return false;
- }
-
- public void replicate(Object key)
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- getClass().getName());
- }
-
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/FileObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/FileObjectStore.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/FileObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,244 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-import org.jboss.ejb3.cache.Identifiable;
-import org.jboss.ejb3.cache.ObjectStore;
-import org.jboss.logging.Logger;
-import org.jboss.serial.io.JBossObjectInputStream;
-import org.jboss.serial.io.JBossObjectOutputStream;
-
-/**
- * Stores objects in a directory via serialization.
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision: $
- */
-public class FileObjectStore<T extends Identifiable> implements ObjectStore<T>
-{
- private static final Logger log = Logger.getLogger(FileObjectStore.class);
-
- private File storageDirectory;
-
- private static class DeleteFileAction implements PrivilegedAction<Boolean>
- {
- File file;
-
- DeleteFileAction(File file)
- {
- this.file = file;
- }
-
- public Boolean run()
- {
- return file.delete();
- }
-
- static boolean delete(File file)
- {
- DeleteFileAction action = new DeleteFileAction(file);
- return AccessController.doPrivileged(action);
- }
- }
-
- private static class FISAction implements PrivilegedExceptionAction<FileInputStream>
- {
- File file;
-
- FISAction(File file)
- {
- this.file = file;
- }
-
- public FileInputStream run() throws FileNotFoundException
- {
- FileInputStream fis = new FileInputStream(file);
- return fis;
- }
-
- static FileInputStream open(File file) throws FileNotFoundException
- {
- FISAction action = new FISAction(file);
- FileInputStream fis = null;
- try
- {
- fis = AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException e)
- {
- throw (FileNotFoundException) e.getException();
- }
- return fis;
- }
- }
-
- private static class FOSAction implements PrivilegedExceptionAction<FileOutputStream>
- {
- File file;
-
- FOSAction(File file)
- {
- this.file = file;
- }
-
- public FileOutputStream run() throws FileNotFoundException
- {
- FileOutputStream fis = new FileOutputStream(file);
- return fis;
- }
-
- static FileOutputStream open(File file) throws FileNotFoundException
- {
- FOSAction action = new FOSAction(file);
- FileOutputStream fos = null;
- try
- {
- fos = AccessController.doPrivileged(action);
- }
- catch (PrivilegedActionException e)
- {
- throw (FileNotFoundException) e.getException();
- }
- return fos;
- }
- }
-
- private static class MkdirsFileAction implements PrivilegedAction<Boolean>
- {
- File file;
-
- MkdirsFileAction(File file)
- {
- this.file = file;
- }
-
- public Boolean run()
- {
- return file.mkdirs();
- }
-
- static boolean mkdirs(File file)
- {
- MkdirsFileAction action = new MkdirsFileAction(file);
- return AccessController.doPrivileged(action);
- }
- }
-
- protected File getFile(Object key)
- {
- return new File(storageDirectory, String.valueOf(key) + ".ser");
- }
-
- @SuppressWarnings("unchecked")
- public T load(Object key)
- {
- File file = getFile(key);
- if(!file.exists())
- return null;
-
- log.debug("loading state from " + file);
- try
- {
- FileInputStream fis = FISAction.open(file);
- ObjectInputStream in = new JBossObjectInputStream(fis);
- try
- {
- return (T) in.readObject();
- }
- finally
- {
- in.close();
- DeleteFileAction.delete(file);
- }
- }
- catch(ClassNotFoundException e)
- {
- throw new RuntimeException("failed to load object " + key, e);
- }
- catch(IOException e)
- {
- throw new RuntimeException("failed to load object " + key, e);
- }
- }
-
- public void setStorageDirectory(String dirName)
- {
- storageDirectory = new File(dirName);
- }
-
- public void start()
- {
- assert storageDirectory != null : "storageDirectory is null";
-
- if(!storageDirectory.exists())
- {
- if(!MkdirsFileAction.mkdirs(storageDirectory))
- throw new RuntimeException("Unable to create storage directory " + storageDirectory);
- storageDirectory.deleteOnExit();
- }
-
- if(!storageDirectory.isDirectory())
- throw new RuntimeException("Storage directory " + storageDirectory + " is not a directory");
- }
-
- public void stop()
- {
- // TODO: implement
- }
-
- public void store(T obj)
- {
- File file = getFile(obj.getId());
- file.deleteOnExit();
- log.debug("saving state to " + file);
- try
- {
- FileOutputStream fos = FOSAction.open(file);
- ObjectOutputStream out = new JBossObjectOutputStream(fos);
- try
- {
- out.writeObject(obj);
- out.flush();
- }
- finally
- {
- out.close();
- }
- }
- catch(IOException e)
- {
- throw new RuntimeException("failed to store object " + obj.getId(), e);
- }
- }
-}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupAwareTransactionalCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.SerializationGroup;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.GroupAwareBackingCache;
+import org.jboss.ejb3.cache.spi.GroupIncompatibilityException;
+
+/**
+ * {@link Cache#isGroupAware Group-aware} version of {@link TransactionalCache}.
+ *
+ * @author Brian Stansberry
+ */
+public class GroupAwareTransactionalCache<C extends CacheItem, T extends BackingCacheEntry<C>>
+ extends TransactionalCache<C, T>
+{
+ @SuppressWarnings("unchecked")
+ private static final ThreadLocal groupCreationContext = new ThreadLocal();
+
+ /**
+ * Another ref to super.delegate. Just saves having to do casts all the time.
+ */
+ private final GroupAwareBackingCache<C, T> groupedCache;
+
+ /**
+ * Create a new GroupAwareTransactionalCacheImpl.
+ *
+ * @param delegate the backing cache
+ * @param tm the transaction manager
+ */
+ public GroupAwareTransactionalCache(GroupAwareBackingCache<C, T> delegate,
+ TransactionManager tm)
+ {
+ super(delegate, tm);
+ this.groupedCache = delegate;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public C create(Class<?>[] initTypes, Object[] initValues)
+ {
+ boolean outer = false;
+ List<ItemCachePair> contextPairs = (List<ItemCachePair>) groupCreationContext.get();
+ if (contextPairs == null)
+ {
+ contextPairs = new ArrayList<ItemCachePair>();
+ groupCreationContext.set(contextPairs);
+ outer = true;
+ }
+
+ C cacheItem = super.create(initTypes, initValues);
+
+ contextPairs.add(new ItemCachePair(cacheItem, this));
+
+ if (outer)
+ {
+ groupCreationContext.set(null);
+ if (contextPairs.size() > 1)
+ {
+ SerializationGroup<C> group = null;
+ try
+ {
+ boolean skipped = false;
+ boolean added = false;
+ for (ItemCachePair pair : contextPairs)
+ {
+ if (pair.cache.isGroupAware())
+ {
+ if (skipped)
+ throw new GroupIncompatibilityException("Some caches in nested bean hierarchy are group-aware, some are not");
+
+ if (group == null)
+ {
+ group = pair.cache.createGroup();
+ }
+ pair.cache.setGroup(pair.item, group);
+ added = true;
+ }
+ else if (added)
+ {
+ throw new GroupIncompatibilityException("Some caches in nested bean hierarchy are group-aware, some are not");
+ }
+ else
+ {
+ skipped = true;
+ }
+ }
+ }
+ catch (GroupIncompatibilityException e)
+ {
+ // Clean up
+ for (ItemCachePair pair : contextPairs)
+ {
+ pair.cache.remove(pair.item.getId());
+ }
+ throw new RuntimeException("Failed to create SerializationGroup for nested bean hierarchy", e);
+ }
+ }
+ }
+
+ return cacheItem;
+ }
+
+ @Override
+ public boolean isGroupAware()
+ {
+ return true;
+ }
+
+ private void setGroup(C obj, SerializationGroup<C> group) throws GroupIncompatibilityException
+ {
+ groupedCache.setGroup(obj, group);
+ }
+
+ private SerializationGroup<C> createGroup() throws GroupIncompatibilityException
+ {
+ return groupedCache.createGroup();
+ }
+
+ @Override
+ public SerializationGroup<C> getGroup(C obj)
+ {
+ return groupedCache.getGroup(obj);
+ }
+
+ private class ItemCachePair
+ {
+ private final C item;
+ private final GroupAwareTransactionalCache<C, T> cache;
+
+ ItemCachePair(C item, GroupAwareTransactionalCache<C, T> cache)
+ {
+ this.item = item;
+ this.cache = cache;
+ }
+ }
+
+}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,297 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.ejb.NoSuchEJBException;
-
-import org.jboss.ejb3.cache.Identifiable;
-import org.jboss.ejb3.cache.ObjectStore;
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.PassivationManager;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-import org.jboss.ejb3.cache.grouped.GroupedPassivatingCache;
-import org.jboss.ejb3.cache.grouped.SerializationGroup;
-import org.jboss.ejb3.cache.grouped.SerializationGroupMember;
-import org.jboss.logging.Logger;
-
-/**
- * Comment
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision$
- */
-public class GroupedPassivatingCacheImpl<T extends Identifiable & Serializable> implements GroupedPassivatingCache<T>
-{
- private static final Logger log = Logger.getLogger(GroupedPassivatingCacheImpl.class);
-
- private PassivatingCache<SerializationGroup> groupCache;
-
- private SimplePassivatingCache<Entry<T>> delegate;
- private Map<Object, Entry<T>> storage = new HashMap<Object, Entry<T>>();
-
- protected class Entry<C extends Identifiable & Serializable>
- implements SerializationGroupMember, Serializable
- {
- private static final long serialVersionUID = 1L;
-
- Object id;
- C obj;
- SerializationGroup group;
- Object groupId;
-
- Entry(C obj)
- {
- assert obj != null : "obj is null";
-
- this.obj = obj;
- this.id = obj.getId();
- }
-
- public Object getId()
- {
- return id;
- }
-
- public C getSerializableObject()
- {
- return obj;
- }
-
- public void prePassivate()
- {
- // make sure we don't passivate the group twice
- group = null;
-
- delegate.passivate(this.id);
-
- obj = null;
- }
-
- public void preReplicate()
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- GroupedPassivatingCacheImpl.this.getClass().getName());
- }
-
- public boolean isClustered()
- {
- return false;
- }
-
- @Override
- public String toString()
- {
- return super.toString() + "{id=" + id + ",obj=" + obj + ",groupId=" + groupId + ",group=" + group + "}";
- }
- }
-
- private class EntryContainer implements StatefulObjectFactory<Entry<T>>, PassivationManager<Entry<T>>, ObjectStore<Entry<T>>
- {
- private StatefulObjectFactory<T> factory;
- private PassivationManager<T> passivationManager;
- private ObjectStore<T> store;
-
- EntryContainer(StatefulObjectFactory<T> factory, PassivationManager<T> passivationManager, ObjectStore<T> store)
- {
- this.factory = factory;
- this.passivationManager = passivationManager;
- this.store = store;
- }
-
- public Entry<T> create(Class<?>[] initTypes, Object[] initValues)
- {
- return new Entry<T>(factory.create(initTypes, initValues));
- }
-
- public void destroy(Entry<T> entry)
- {
- factory.destroy(entry.getSerializableObject());
- }
-
- public Entry<T> load(Object key)
- {
- Entry<T> entry = storage.get(key);
- if(entry != null)
- {
- log.trace("entry = " + entry);
- return entry;
- }
- // This only happens when there is no group
- T obj = store.load(key);
- if(obj == null)
- return null;
- return new Entry<T>(obj);
- }
-
- @SuppressWarnings("unchecked")
- public void postActivate(Entry<T> entry)
- {
- log.trace("post activate " + entry);
- if(entry.getSerializableObject() == null)
- {
- if(entry.group == null)
- {
- // TODO: peek or get?
- entry.group = groupCache.peek(entry.groupId);
- }
- entry.obj = (T) entry.group.getMemberObject(entry.id);
- entry.group.addActive(entry);
- }
- passivationManager.postActivate(entry.obj);
- }
-
- public void prePassivate(Entry<T> entry)
- {
- log.trace("pre passivate " + entry);
- passivationManager.prePassivate(entry.obj);
- // Am I being called recursively
- if(entry.group != null)
- {
- entry.group.removeActive(entry.id);
- entry.group.prePassivate();
- groupCache.passivate(entry.groupId);
- // Why clear? Because entry is removed from active, and thus passivate is never called.
- entry.group = null;
- entry.obj = null;
- }
- }
-
- public boolean isClustered()
- {
- return false;
- }
-
- public void preReplicate(Entry<T> entry)
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- getClass().getName());
- }
-
- public void postReplicate(Entry<T> entry)
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- getClass().getName());
- }
-
- public void store(Entry<T> entry)
- {
- log.trace("store " + entry);
- if(entry.groupId == null)
- store.store(entry.obj);
- else
- storage.put(entry.id, entry);
- }
- }
-
- public GroupedPassivatingCacheImpl(StatefulObjectFactory<T> factory, PassivationManager<T> passivationManager, ObjectStore<T> store, PassivatingCache<SerializationGroup> groupCache)
- {
- assert groupCache != null : "groupCache is null";
- assert passivationManager != null : "passivationManager is null";
- assert groupCache.isClustered() == false : "groupCache should not be clustered";
-
- this.groupCache = groupCache;
- EntryContainer container = new EntryContainer(factory, passivationManager, store);
- this.delegate = new SimplePassivatingCache<Entry<T>>(container, container, container);
- }
-
- public boolean isClustered()
- {
- return false;
- }
-
- public void replicate(Object key)
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- getClass().getName());
- }
-
- public void passivate(Object key)
- {
- delegate.passivate(key);
- }
-
- public T create(Class<?>[] initTypes, Object[] initValues)
- {
- return delegate.create(initTypes, initValues).obj;
- }
-
- public T get(Object key) throws NoSuchEJBException
- {
- return delegate.get(key).obj;
- }
-
- public T peek(Object key) throws NoSuchEJBException
- {
- return delegate.peek(key).obj;
- }
-
- public void release(T obj)
- {
- delegate.releaseByKey(obj.getId());
- }
-
- public void remove(Object key)
- {
- delegate.remove(key);
- }
-
-
- public void setGroup(T obj, SerializationGroup group)
- {
- if (group.isClustered())
- {
- throw new IllegalArgumentException(group + " is clustered; this cache does not support clustering");
- }
- Object key = obj.getId();
- Entry<T>entry = delegate.peek(key);
- if(entry.group != null)
- throw new IllegalStateException("object " + key + " already associated with a passivation group");
- entry.group = group;
- entry.groupId = group.getId();
- // TODO: remove member at the appropriate time
- entry.group.addMember(entry);
- }
-
- public void setName(String name)
- {
- delegate.setName(name + "-delegate");
- }
-
- public void setSessionTimeout(int sessionTimeout)
- {
- delegate.setSessionTimeout(sessionTimeout);
- }
-
- public void start()
- {
- delegate.start();
- }
-
- public void stop()
- {
- delegate.stop();
- }
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl2.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl2.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/GroupedPassivatingCacheImpl2.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,376 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.io.Serializable;
-
-import javax.ejb.NoSuchEJBException;
-
-import org.jboss.ejb3.cache.Cacheable;
-import org.jboss.ejb3.cache.IntegratedObjectStore;
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.PassivatingIntegratedObjectStore;
-import org.jboss.ejb3.cache.PassivationManager;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-import org.jboss.ejb3.cache.grouped.GroupedPassivatingCache;
-import org.jboss.ejb3.cache.grouped.SerializationGroup;
-import org.jboss.logging.Logger;
-
-/**
- * {@link GroupedPassivatingCache} that uses an {@link IntegratedObjectStore}
- * to manage data.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public class GroupedPassivatingCacheImpl2<T extends Cacheable & Serializable> implements GroupedPassivatingCache<T>
-{
- private static final Logger log = Logger.getLogger(GroupedPassivatingCacheImpl2.class);
-
- /**
- * Cache that's managing the PassivationGroup
- */
- private PassivatingCache<SerializationGroup> groupCache;
-
- /**
- * Delegate that handles the usual details; ends up calling into
- * our EntryContainer for StatefulObjectFactory, PassivationManager
- * and IntegratedObjectStore functions.
- */
- private SimplePassivatingCache2<SerializationGroupMemberImpl<T>> delegate;
-
- /**
- * Do we support clustering? This field is really just a minor
- * optimization to avoid calling through to the underlying
- * IntegratedObjectStore all the time.
- */
- private boolean clustered;
-
- private EntryContainer entryContainer;
-
- private class EntryContainer
- implements StatefulObjectFactory<SerializationGroupMemberImpl<T>>, PassivationManager<SerializationGroupMemberImpl<T>>, IntegratedObjectStore<SerializationGroupMemberImpl<T>>
- {
- private StatefulObjectFactory<T> factory;
- private PassivationManager<T> passivationManager;
- private IntegratedObjectStore<SerializationGroupMemberImpl<T>> store;
-
- EntryContainer(StatefulObjectFactory<T> factory, PassivationManager<T> passivationManager, IntegratedObjectStore<SerializationGroupMemberImpl<T>> store)
- {
- this.factory = factory;
- this.passivationManager = passivationManager;
- this.store = store;
- }
-
- public SerializationGroupMemberImpl<T> create(Class<?>[] initTypes, Object[] initValues)
- {
- return new SerializationGroupMemberImpl<T>(factory.create(initTypes, initValues),
- delegate);
- }
-
- public void destroy(SerializationGroupMemberImpl<T> entry)
- {
- factory.destroy(entry.getSerializableObject());
- if (entry.getGroup() != null)
- {
- entry.getGroup().removeMember(entry.getId());
- if (entry.getGroup().size() == 0)
- {
- groupCache.remove(entry.getGroupId());
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- public void postActivate(SerializationGroupMemberImpl<T> entry)
- {
- log.trace("post activate " + entry);
-
- // Restore the entry's ref to the group and object
- if(entry.getGroup() == null)
- {
- // TODO: peek or get?
- // BES 2007/10/06 I think peek is better; no
- // sense marking the group as in-use and then having
- // to release it or something
- entry.setGroup(groupCache.peek(entry.getGroupId()));
- }
-
- if(entry.getGroup() != null)
- {
- entry.setSerializableObject((T) entry.getGroup().getMemberObject(entry.getId()));
-
- // Notify the group that this entry is active
- entry.getGroup().addActive(entry);
- }
-
- // Invoke callbacks on the underlying object
- passivationManager.postActivate(entry.getSerializableObject());
- }
-
- public void prePassivate(SerializationGroupMemberImpl<T> entry)
- {
- log.trace("pre-passivate " + entry);
-
- // entry.obj may or may not get serialized (depends on if group
- // is in use) but it's ok to invoke callbacks now. If a caller
- // requests this entry again and the obj hadn't been serialized with
- // the group, we'll just call postActivate on it then, which is OK.
- // By always invoking the callbacks here, we avoid possible bugs
- // where they sometimes don't get called.
- passivationManager.prePassivate(entry.getSerializableObject());
-
- // If this call is coming via delegate.passivate(), entry.group will
- // *not* be null. In that case we are the controller for the
- // group passivation. If the call is coming via Entry.prePassivate(),
- // entry.group *will* be null. In that case we are not the controller
- // of the passivation and can just return.
- if(entry.getGroup() != null)
- {
- // Remove ourself from group's active list so we don't get
- // called again via Entry.prePassivate()
- entry.getGroup().removeActive(entry.getId());
-
- // Only tell the group to passivate if no members are in use
- if (!entry.getGroup().isInUse())
- {
- // Tell group to prePassivate other active members
- entry.getGroup().prePassivate();
- // Go ahead and do the real passivation
- groupCache.passivate(entry.getGroupId());
- }
- // else {
- // this turns into a pretty meaningless exercise of just
- // passivating an empty Entry. TODO consider throwing
- // ItemInUseException here, thus aborting everything. Need to
- // be sure that doesn't lead to problems as the exception propagates
- // }
-
- // This call didn't come through Entry.prePassivate() (which nulls
- // group and obj) so we have to do it ourselves. Otherwise
- // when this call returns, delegate will serialize the entry
- // with a ref to group and obj.
- entry.setGroup(null);
- entry.setSerializableObject(null);
- }
- }
-
- public void preReplicate(SerializationGroupMemberImpl<T> entry)
- {
- // This method follows the same conceptual logic as prePassivate.
- // See the detailed comments in that method.
-
- log.trace("pre-replicate " + entry);
-
- passivationManager.preReplicate(entry.getSerializableObject());
-
- if(entry.getGroup() != null)
- {
- entry.getGroup().removeActive(entry.getId());
-
- try
- {
- if (!entry.getGroup().isInUse())
- {
- entry.getGroup().preReplicate();
- groupCache.replicate(entry.getGroupId());
- }
- }
- finally
- {
- // Here we differ from prePassivate!!
- // Restore the entry as "active" so it can get
- // passivation callbacks
- entry.getGroup().addActive(entry);
- }
-
- entry.setGroup(null);
- entry.setSerializableObject(null);
- }
- }
-
- @SuppressWarnings("unchecked")
- public void postReplicate(SerializationGroupMemberImpl<T> entry)
- {
- log.trace("postreplicate " + entry);
-
- // Restore the entry's ref to the group and object
- if(entry.getGroup() == null)
- {
- // TODO: peek or get?
- // BES 2007/10/06 I think peek is better; no
- // sense marking the group as in-use and then having
- // to release it or something
- entry.setGroup(groupCache.peek(entry.getGroupId()));
- }
-
- if(entry.getGroup() != null)
- {
- entry.setSerializableObject((T) entry.getGroup().getMemberObject(entry.getId()));
-
- // Notify the group that this entry is active
- entry.getGroup().addActive(entry);
- }
-
- // Invoke callbacks on the underlying object
- passivationManager.postReplicate(entry.getSerializableObject());
- }
-
- public void update(SerializationGroupMemberImpl<T> entry)
- {
- store.update(entry);
- }
-
- public boolean isClustered()
- {
- // Use value from containing cache; containing cache c'tor ensures
- // the underlying store matches this
- return clustered;
- }
-
- public SerializationGroupMemberImpl<T> get(Object key)
- {
- SerializationGroupMemberImpl<T> entry = store.get(key);
- // In case it was deserialized, make sure it has a ref to us
- entry.setPassivatingCache(delegate);
- return entry;
- }
-
- public void passivate(SerializationGroupMemberImpl<T> entry)
- {
- store.passivate(entry);
- }
-
- public void insert(SerializationGroupMemberImpl<T> entry)
- {
- store.insert(entry);
- }
-
- public SerializationGroupMemberImpl<T> remove(Object key)
- {
- return store.remove(key);
- }
-
- public void start()
- {
- store.start();
- }
-
- public void stop()
- {
- store.stop();
- }
- }
-
- public GroupedPassivatingCacheImpl2(StatefulObjectFactory<T> factory, PassivationManager<T> passivationManager, IntegratedObjectStore<SerializationGroupMemberImpl<T>> store, PassivatingCache<SerializationGroup> groupCache)
- {
- assert groupCache != null : "groupCache is null";
- assert passivationManager != null : "passivationManager is null";
- assert store != null : "store is null";
- assert groupCache.isClustered() == store.isClustered(): "incompatible clustering support between groupCache and store";
- assert groupCache.isClustered() == passivationManager.isClustered(): "incompatible clustering support between groupCache and passivationManager";
-
- this.clustered = store.isClustered();
- this.groupCache = groupCache;
- entryContainer = new EntryContainer(factory, passivationManager, store);
- this.delegate = new SimplePassivatingCache2<SerializationGroupMemberImpl<T>>(entryContainer, entryContainer, entryContainer);
-
- // We pass 'entryContainer' to the delegate, and that's not a PassivatingIntegratedObjectStore
- // so delegate won't provide the real store with a ref. So we do it here.
- if (store instanceof PassivatingIntegratedObjectStore)
- {
- ((PassivatingIntegratedObjectStore<SerializationGroupMemberImpl<T>>) store).setPassivatingCache(delegate);
- }
- }
-
- public boolean isClustered()
- {
- return clustered;
- }
-
- public void replicate(Object key)
- {
- delegate.replicate(key);
- }
-
- public void passivate(Object key)
- {
- delegate.passivate(key);
- }
-
- public T create(Class<?>[] initTypes, Object[] initValues)
- {
- return delegate.create(initTypes, initValues).getSerializableObject();
- }
-
- public T get(Object key) throws NoSuchEJBException
- {
- SerializationGroupMemberImpl<T> entry = delegate.get(key);
- if (entry.getGroup() != null)
- {
- entry.getGroup().addInUse(key);
- }
- return entry.getSerializableObject();
- }
-
- public T peek(Object key) throws NoSuchEJBException
- {
- return delegate.peek(key).getSerializableObject();
- }
-
- public void release(T obj)
- {
- Object key = obj.getId();
- SerializationGroupMemberImpl<T> entry = delegate.releaseByKey(key);
- if (entry.getGroup() != null)
- {
- entry.getGroup().removeInUse(key);
- }
- }
-
- public void remove(Object key)
- {
- delegate.remove(key);
- }
-
- public void setGroup(T obj, SerializationGroup group)
- {
- SerializationGroupMemberImpl<T> entry;
- Object key = obj.getId();
- entry = delegate.peek(key);
- if(entry.getGroup() != null)
- throw new IllegalStateException("object " + key + " already associated with a passivation group");
- entry.setGroup(group);
- entry.setGroupId(group.getId());
- entry.getGroup().addMember(entry);
- }
-
- public void start()
- {
- delegate.start();
- }
-
- public void stop()
- {
- delegate.stop();
- }
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupContainer.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupContainer.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupContainer.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,97 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import org.jboss.ejb3.cache.PassivationManager;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-import org.jboss.ejb3.cache.grouped.SerializationGroup;
-import org.jboss.logging.Logger;
-
-/**
- * Comment
- *
- * FIXME determine whether SerializationGroup clustering support should
- * be controlled by a property of this container or via a param passed
- * to create().
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision: $
- */
-public class SerializationGroupContainer implements StatefulObjectFactory<SerializationGroup>, PassivationManager<SerializationGroup>
-{
- private static final Logger log = Logger.getLogger(SerializationGroupContainer.class);
-
- private boolean clustered;
-
- public boolean isClustered()
- {
- return clustered;
- }
-
- public void setClustered(boolean clustered)
- {
- this.clustered = clustered;
- }
-
- public SerializationGroup create(Class<?>[] initTypes, Object[] initValues)
- {
- SerializationGroup group = new SerializationGroupImpl();
- // TODO should this be controlled via one of the initValues?
- group.setClustered(clustered);
- return group;
- }
-
- public void destroy(SerializationGroup obj)
- {
- // TODO: nothing?
- }
-
- public void postActivate(SerializationGroup obj)
- {
- log.trace("post activate " + obj);
- obj.postActivate();
- }
-
- public void prePassivate(SerializationGroup obj)
- {
- log.trace("pre passivate " + obj);
- obj.prePassivate();
- }
-
- public void postReplicate(SerializationGroup obj)
- {
- if (!clustered)
- throw new UnsupportedOperationException("Clustering not supported");
- log.trace("post replicate " + obj);
- obj.postReplicate();
- }
-
- public void preReplicate(SerializationGroup obj)
- {
- if (!clustered)
- throw new UnsupportedOperationException("Clustering not supported");
- log.trace("pre replicate " + obj);
- obj.preReplicate();
- }
-
-
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupImpl.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,205 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.ejb3.cache.grouped.SerializationGroup;
-import org.jboss.ejb3.cache.grouped.SerializationGroupMember;
-import org.jboss.logging.Logger;
-import org.jboss.util.id.GUID;
-
-/**
- * Default implementation of {@link SerializationGroup}.
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @author Brian Stansberry
- * @version $Revision: $
- */
-public class SerializationGroupImpl implements SerializationGroup
-{
- private static final Logger log = Logger.getLogger(SerializationGroupImpl.class);
- private static final long serialVersionUID = 1L;
-
- private Object id = new GUID();
- /**
- * The actual underlying objects passed in via addMember(). We store them
- * here so they aren't lost when they are cleared from the values
- * stored in the "members" map.
- */
- private Map<Object, Object> memberObjects = new HashMap<Object, Object>();
- /**
- * The active group members. We don't serialized these. Rather, it is
- * the responsibility of members to reassociate themselves with the
- * group upon deserialization (via addActive())
- */
- private transient Map<Object, SerializationGroupMember> active =
- new HashMap<Object, SerializationGroupMember>();
- /**
- * Set of keys passed to {@link #addInUse(Object)}
- */
- private transient Set<Object> inUseKeys = new HashSet<Object>();
-
- private boolean clustered;
-
- private long lastUsed;
-
- public Object getId()
- {
- return id;
- }
-
- public boolean isClustered()
- {
- return clustered;
- }
-
- public void setClustered(boolean clustered)
- {
- this.clustered = clustered;
- }
-
- public void addMember(SerializationGroupMember member)
- {
- Object key = member.getId();
- if (memberObjects.containsKey(key))
- throw new IllegalStateException(member + " is already a member");
- log.trace("add member " + key + ", " + member);
- memberObjects.put(key, member.getSerializableObject());
- active.put(key, member);
- }
-
- public void removeMember(Object key)
- {
- removeActive(key);
- memberObjects.remove(key);
- }
-
- public int size()
- {
- return memberObjects.size();
- }
-
- public Object getMemberObject(Object key)
- {
- return memberObjects.get(key);
- }
-
- public void postActivate()
- {
- // do nothing
- }
-
- public void prePassivate()
- {
- for(SerializationGroupMember member : active.values())
- {
- member.prePassivate();
- }
- active.clear();
- }
-
- public void postReplicate()
- {
- // do nothing
- }
-
- public void preReplicate()
- {
- for(SerializationGroupMember member : active.values())
- {
- member.preReplicate();
- }
- active.clear();
- }
-
- public void addActive(SerializationGroupMember member)
- {
- Object key = member.getId();
- if (!memberObjects.containsKey(key))
- throw new IllegalStateException(member + " is not a member of " + this);
- active.put(key, member);
- }
-
- public void removeActive(Object key)
- {
- active.remove(key);
- }
-
- public void addInUse(Object key)
- {
- if (!memberObjects.containsKey(key))
- throw new IllegalStateException(key + " is not a member of " + this);
- inUseKeys.add(key);
- lastUsed = System.currentTimeMillis();
- }
-
- public void removeInUse(Object key)
- {
- if (inUseKeys.remove(key))
- {
- lastUsed = System.currentTimeMillis();
- }
- else if (!memberObjects.containsKey(key))
- {
- throw new IllegalStateException(key + " is not a member of " + this);
- }
- }
-
- public long getLastUsed()
- {
- return lastUsed;
- }
-
- public boolean isInUse()
- {
- return inUseKeys.size() > 0;
- }
-
- public void setInUse(boolean inUse)
- {
- lastUsed = System.currentTimeMillis();
- }
-
- /**
- * Always returns <code>true</code>.
- */
- public boolean isModified()
- {
- return true;
- }
-
- private void readObject(java.io.ObjectInputStream in)
- throws IOException, ClassNotFoundException
- {
- in.defaultReadObject();
- active = new HashMap<Object, SerializationGroupMember>();
- inUseKeys = new HashSet<Object>();
- }
-
-
-
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupMemberImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupMemberImpl.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupMemberImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,166 +0,0 @@
-package org.jboss.ejb3.cache.impl;
-
-import java.io.Serializable;
-
-import org.jboss.ejb3.cache.Cacheable;
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.grouped.SerializationGroup;
-import org.jboss.ejb3.cache.grouped.SerializationGroupMember;
-
-/**
- * Default implementation of {@link SerializationGroupMember}.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public class SerializationGroupMemberImpl<T extends Cacheable & Serializable>
- implements Cacheable, SerializationGroupMember, Serializable
-{
- private static final long serialVersionUID = 1L;
-
- private Object id;
- /**
- * The underlying object (e.g. bean context).
- * Preferably, this field would be transient. It isn't now because it is
- * possible this entry will never be assigned to a PassivationGroup,
- * in which case we need to serialize obj.
- * TODO Relying on nulling this field is fragile. Can we make this
- * field transient by ensuring we only use this cache class with bean
- * classes that are sure to be part of a group?
- */
- private T obj;
- /**
- * Hack. We hold two refs to our object; one we clear in prePassivate,
- * one we keep, but it's transient. getSerializableObject() returns
- * whichever is available, making it available for passivation callbacks.
- */
- private transient T transientObj;
- /** The group. Never serialize the group; only the groupCache does that */
- private transient SerializationGroup group;
- private Object groupId;
- private long lastUsed;
- /** The cache that's handling us */
- private transient PassivatingCache<SerializationGroupMemberImpl<T>> delegate;
-
- SerializationGroupMemberImpl(T obj, PassivatingCache<SerializationGroupMemberImpl<T>> delegate)
- {
- assert obj != null : "obj is null";
- assert delegate != null : "delegate is null";
-
- this.obj = transientObj = obj;
- this.id = obj.getId();
- this.delegate = delegate;
- }
-
- public Object getId()
- {
- return id;
- }
-
- public boolean isClustered()
- {
- // Value from the containing cache
- return delegate.isClustered();
- }
-
- @SuppressWarnings("unchecked")
- public T getSerializableObject()
- {
- return obj == null ? transientObj : obj;
- }
-
- public void setSerializableObject(T obj)
- {
- this.obj = transientObj = obj;
- }
-
- public SerializationGroup getGroup()
- {
- return group;
- }
-
- public void setGroup(SerializationGroup group)
- {
- this.group = group;
- }
-
- public Object getGroupId()
- {
- return groupId;
- }
-
- public void setGroupId(Object groupId)
- {
- this.groupId = groupId;
- }
-
- // Called by PassivationGroup prior to its passivating
- public void prePassivate()
- {
- // make sure we don't passivate the group twice
- group = null;
-
- // null out obj so when delegate passivates this entry
- // we don't serialize it. It serializes with the PassivationGroup only
- // We still have a ref to transientObj, so it can be retrieved
- // for passivation callbacks
- obj = null;
-
- delegate.passivate(this.id);
- }
-
- // Called by PassivationGroup prior to its replicating
- public void preReplicate()
- {
- // make sure we don't replicate the group twice
- group = null;
- // null out obj so when delegate passivates this entry
- // we don't serialize it. It serializes with the PassivationGroup only
- obj = null;
-
- delegate.replicate(this.id);
- }
-
- public long getLastUsed()
- {
- return obj == null ? lastUsed : obj.getLastUsed();
- }
-
- public boolean isInUse()
- {
- return obj == null ? false : obj.isInUse();
- }
-
- public void setInUse(boolean inUse)
- {
- if (obj != null)
- {
- obj.setInUse(inUse);
- lastUsed = obj.getLastUsed();
- }
- }
-
- /**
- * Allows our controlling {@link PassivatingCache} to provide
- * us a reference after deserialization.
- *
- * @param delegate
- */
- public void setPassivatingCache(PassivatingCache<SerializationGroupMemberImpl<T>> delegate)
- {
- assert delegate != null : "delegate is null";
-
- this.delegate = delegate;
- }
-
- public boolean isModified()
- {
- return (obj != null && obj.isModified());
- }
-
- @Override
- public String toString()
- {
- return super.toString() + "{id=" + id + ",obj=" + obj + ",groupId=" + groupId + ",group=" + group + "}";
- }
-}
\ No newline at end of file
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleCache.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,115 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.ejb.NoSuchEJBException;
-
-import org.jboss.ejb3.cache.Cache;
-import org.jboss.ejb3.cache.Identifiable;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-
-/**
- * Comment
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision: $
- */
-public class SimpleCache<T extends Identifiable> implements Cache<T>
-{
- private StatefulObjectFactory<T> factory;
- private Map<Object, T> cache;
-
- public SimpleCache(StatefulObjectFactory<T> factory)
- {
- assert factory != null;
-
- this.factory = factory;
- this.cache = new HashMap<Object, T>();
- }
-
- public T create(Class<?>[] initTypes, Object[] initValues)
- {
- T obj = factory.create(initTypes, initValues);
- synchronized(cache)
- {
- cache.put(obj.getId(), obj);
- }
- return obj;
- }
-
- public T get(Object key) throws NoSuchEJBException
- {
- T obj;
- synchronized (cache)
- {
- obj = cache.get(key);
- }
- if(obj == null)
- throw new NoSuchEJBException(String.valueOf(key));
- return obj;
- }
-
- public T peek(Object key) throws NoSuchEJBException
- {
- return get(key);
- }
-
- public void release(T obj)
- {
- // release does nothing
- }
-
- public void remove(Object key)
- {
- T obj;
- synchronized (cache)
- {
- obj = cache.remove(key);
- }
- if(obj != null)
- factory.destroy(obj);
- }
-
- public boolean isClustered()
- {
- return false;
- }
-
- public void replicate(Object key)
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- getClass().getName());
- }
-
- public void start()
- {
- // do nothing
- }
-
- public void stop()
- {
- // do nothing
- }
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleIntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleIntegratedObjectStore.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimpleIntegratedObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,366 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.ejb3.cache.impl;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.jboss.ejb3.cache.Cacheable;
-import org.jboss.ejb3.cache.IntegratedObjectStore;
-import org.jboss.ejb3.cache.ObjectStore;
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.PassivatingIntegratedObjectStore;
-import org.jboss.logging.Logger;
-
-/**
- * A {@link IntegratedObjectStore} that delegates to a provided
- * {@link ObjectStore} for persistence.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public class SimpleIntegratedObjectStore<T extends Cacheable & Serializable>
- implements PassivatingIntegratedObjectStore<T>
-{
- private static final Logger log = Logger.getLogger(SimpleIntegratedObjectStore.class);
-
- private final ObjectStore<T> store;
- private Map<Object, T> cache;
- private Map<Object, Long> passivatedEntries;
-
- /**
- * Support callbacks when our SessionTimeoutThread decides to
- * evict an entry.
- */
- private PassivatingCache<T> owningCache;
- private int interval;
- private int idleTimeSeconds;
- private int expirationTimeSeconds;
- private SessionTimeoutRunner sessionTimeoutRunner;
- private String name;
-
- /**
- * Create a new SimpleIntegratedObjectStore.
- *
- */
- public SimpleIntegratedObjectStore(ObjectStore<T> store)
- {
- this.store = store;
- this.cache = new HashMap<Object, T>();
- this.passivatedEntries = new HashMap<Object, Long>();
- }
-
- public boolean isClustered()
- {
- return false;
- }
-
- public T get(Object key)
- {
- synchronized (cache)
- {
- T entry = cache.get(key);
- if(entry == null)
- {
- entry = store.load(key);
- if(entry != null)
- {
- cache.put(key, entry);
- passivatedEntries.remove(key);
- }
- }
- return entry;
- }
- }
-
- public void insert(T entry)
- {
- Object key = entry.getId();
- synchronized (cache)
- {
- if (cache.containsKey(key) || passivatedEntries.containsKey(key))
- {
- throw new IllegalStateException(key + " is already in store");
- }
- cache.put(key, entry);
- }
- }
-
- public void update(T entry)
- {
- Object key = entry.getId();
- synchronized (cache)
- {
- if (!cache.containsKey(key) && !passivatedEntries.containsKey(key))
- {
- throw new IllegalStateException(key + " is not managed by this store");
- }
-
- // Otherwise we do nothing; we already have a ref to the entry
- }
- }
-
- public void passivate(T entry)
- {
- synchronized (cache)
- {
- Object key = entry.getId();
- store.store(entry);
- passivatedEntries.put(key, new Long(entry.getLastUsed()));
- cache.remove(key);
- }
- }
-
- public T remove(Object id)
- {
- synchronized (cache)
- {
- T entry = get(id);
- if (entry != null)
- {
- cache.remove(id);
- }
- return entry;
- }
- }
-
- public void start()
- {
- if (interval > 0)
- {
- if (sessionTimeoutRunner == null)
- {
- assert name != null : "name has not been set";
- assert owningCache != null;
-
- sessionTimeoutRunner = new SessionTimeoutRunner();
- }
- sessionTimeoutRunner.start();
- }
-
- log.debug("Started " + name);
- }
-
- public void stop()
- {
- if (sessionTimeoutRunner != null)
- {
- sessionTimeoutRunner.stop();
- }
-
- log.debug("Stopped " + name);
- }
-
- // --------------------------------------- PassivatingIntegratedObjectStore
-
-
- public void setPassivatingCache(PassivatingCache<T> cache)
- {
- this.owningCache = cache;
- }
-
- public int getInterval()
- {
- return interval;
- }
-
- public void setInterval(int seconds)
- {
- this.interval = seconds;
- }
-
- public void runExpiration()
- {
- if (expirationTimeSeconds > 0)
- {
- long now = System.currentTimeMillis();
- long minRemovalUse = now - (expirationTimeSeconds * 1000);
- for (CacheableTimestamp ts : getPassivatedEntries())
- {
- try
- {
- if (minRemovalUse >= ts.getLastUsed())
- {
- remove(ts.getId());
- }
- }
- catch (IllegalStateException ise)
- {
- // Not so great; we're assuming it's 'cause item's in use
- log.trace("skipping in-use entry " + ts.getId(), ise);
- }
- }
- }
- }
-
- public void runPassivation()
- {
- if (idleTimeSeconds > 0)
- {
- long now = System.currentTimeMillis();
- long minPassUse = now - (idleTimeSeconds * 1000);
-
- // Scan the in-memory entries for passivation or removal
- for (CacheableTimestamp ts : getInMemoryEntries())
- {
- try
- {
- long lastUsed = ts.getLastUsed();
- if (minPassUse >= lastUsed)
- {
- owningCache.passivate(ts.getId());
- }
- }
- catch (IllegalStateException ise)
- {
- // Not so great; we're assuming it's 'cause item's in use
- log.trace("skipping in-use entry " + ts.getId(), ise);
- }
- }
- }
-
- }
-
- public int getIdleTimeSeconds()
- {
- return idleTimeSeconds;
- }
-
- public void setIdleTimeSeconds(int idleTimeSeconds)
- {
- this.idleTimeSeconds = idleTimeSeconds;
- }
-
- public int getExpirationTimeSeconds()
- {
- return expirationTimeSeconds;
- }
-
- public void setExpirationTimeSeconds(int timeout)
- {
- this.expirationTimeSeconds = timeout;
- }
-
- private SortedSet<CacheableTimestamp> getInMemoryEntries()
- {
- SortedSet<CacheableTimestamp> set = new TreeSet<CacheableTimestamp>();
- for (Map.Entry<Object, T> entry : cache.entrySet())
- {
- set.add(new CacheableTimestamp(entry.getKey(), entry.getValue().getLastUsed()));
- }
- return set;
- }
-
- private SortedSet<CacheableTimestamp> getPassivatedEntries()
- {
- SortedSet<CacheableTimestamp> set = new TreeSet<CacheableTimestamp>();
- for (Map.Entry<Object, Long> entry : passivatedEntries.entrySet())
- {
- set.add(new CacheableTimestamp(entry.getKey(), entry.getValue().longValue()));
- }
- return set;
- }
-
- public void setName(String name)
- {
- this.name = name;
- }
-
-
- private class SessionTimeoutRunner implements Runnable
- {
- private boolean stopped = true;
- private Thread thread;
-
- public void run()
- {
- while (!stopped)
- {
- try
- {
- runPassivation();
- }
- catch (Exception e)
- {
- log.error("Caught exception processing passivations", e);
- }
-
- if (!stopped)
- {
- try
- {
- runExpiration();
- }
- catch (Exception e)
- {
- log.error("Caught exception processing expirations", e);
- }
- }
-
- if (!stopped)
- {
- try
- {
- Thread.sleep(interval * 1000);
- }
- catch (InterruptedException ignored) {}
- }
- }
- }
-
- void start()
- {
- if (stopped)
- {
- thread = new Thread(this, "SessionTimeoutRunner-" + name);
- thread.setDaemon(true);
- stopped = false;
- thread.start();
- }
- }
-
- void stop()
- {
- stopped = true;
- if (thread != null && thread.isAlive())
- {
- try
- {
- thread.join(1000);
- }
- catch (InterruptedException ignored) {}
-
- if (thread.isAlive())
- {
- thread.interrupt();
- }
-
- }
- }
-
- }
-
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,309 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.ejb.NoSuchEJBException;
-
-import org.jboss.ejb3.cache.Identifiable;
-import org.jboss.ejb3.cache.ObjectStore;
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.PassivationManager;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-import org.jboss.logging.Logger;
-
-/**
- * Comment
- *
- * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
- * @version $Revision$
- */
-public class SimplePassivatingCache<T extends Identifiable & Serializable> implements PassivatingCache<T>
-{
- private static final Logger log = Logger.getLogger(SimplePassivatingCache.class);
-
- private StatefulObjectFactory<T> factory;
- private PassivationManager<T> passivationManager;
- private ObjectStore<T> store;
-
- private Map<Object, Entry> cache;
-
- private int sessionTimeout = -1;
- private String name;
-
- private Thread sessionTimeoutTask;
-
- private static enum EntryState { READY, IN_USE };
-
- private class Entry
- {
- long lastUsed;
- T obj;
- EntryState state;
-
- Entry(T obj)
- {
- assert obj != null : "obj is null";
-
- this.lastUsed = System.currentTimeMillis();
- this.obj = obj;
- this.state = EntryState.IN_USE;
- }
- }
-
- private class SessionTimeoutThread extends Thread
- {
- public SessionTimeoutThread(String name)
- {
- super(name);
- setDaemon(true);
- }
-
- @Override
- public void run()
- {
- try
- {
- while(!Thread.currentThread().isInterrupted())
- {
- Thread.sleep(1000);
-
- synchronized (cache)
- {
- if(Thread.currentThread().isInterrupted())
- return;
-
- long then = System.currentTimeMillis() - sessionTimeout * 1000;
- Iterator<Entry> it = cache.values().iterator();
- while(it.hasNext())
- {
- Entry entry = it.next();
- if(then >= entry.lastUsed && entry.state != EntryState.IN_USE)
- {
- // TODO: can passivate?
- try
- {
- passivationManager.prePassivate(entry.obj);
- }
- catch(Throwable t)
- {
- log.warn("pre passivate failed for " + entry.obj, t);
- }
-
- store.store(entry.obj);
-
- it.remove();
- }
- }
- }
- }
- }
- catch(InterruptedException e)
- {
- // do nothing
- }
- }
- }
-
- public SimplePassivatingCache(StatefulObjectFactory<T> factory, PassivationManager<T> passivationManager, ObjectStore<T> store)
- {
- assert factory != null : "factory is null";
- assert passivationManager != null : "passivationManager is null";
- assert store != null : "store is null";
-
- this.factory = factory;
- this.passivationManager = passivationManager;
- this.store = store;
- this.cache = new HashMap<Object, Entry>();
- }
-
- public boolean isClustered()
- {
- return false;
- }
-
- public void replicate(Object key)
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- getClass().getName());
- }
-
- public T create(Class<?>[] initTypes, Object[] initValues)
- {
- T obj = factory.create(initTypes, initValues);
- Entry entry = new Entry(obj);
- synchronized (cache)
- {
- cache.put(obj.getId(), entry);
- }
- return obj;
- }
-
- public T get(Object key) throws NoSuchEJBException
- {
- synchronized (cache)
- {
- Entry entry = cache.get(key);
- if(entry == null)
- {
- T obj = store.load(key);
- if(obj != null)
- {
- passivationManager.postActivate(obj);
-
- entry = new Entry(obj);
- cache.put(key, entry);
- return entry.obj;
- }
- }
- if(entry == null)
- throw new NoSuchEJBException(String.valueOf(key));
- if(entry.state != EntryState.READY)
- throw new IllegalStateException("entry " + key + " is not ready");
- entry.state = EntryState.IN_USE;
- entry.lastUsed = System.currentTimeMillis();
- return entry.obj;
- }
- }
-
- public void passivate(Object key)
- {
- log.trace("passivate " + key);
- synchronized (cache)
- {
- Entry entry = cache.get(key);
-
- if(entry == null)
- throw new IllegalArgumentException("entry " + key + " not found in cache " + this);
-
- if(entry.state == EntryState.IN_USE)
- throw new IllegalStateException("entry " + entry + " is in use");
-
- passivationManager.prePassivate(entry.obj);
-
- store.store(entry.obj);
-
- cache.remove(key);
- }
- }
-
- public T peek(Object key) throws NoSuchEJBException
- {
- synchronized (cache)
- {
- Entry entry = cache.get(key);
- if(entry == null)
- {
- T obj = store.load(key);
- if(obj != null)
- {
- passivationManager.postActivate(obj);
-
- entry = new Entry(obj);
- cache.put(key, entry);
- entry.state = EntryState.READY;
- }
- }
- if(entry == null)
- throw new NoSuchEJBException(String.valueOf(key));
- return entry.obj;
- }
- }
-
- public void release(T obj)
- {
- releaseByKey(obj.getId());
- }
-
- protected void releaseByKey(Object key)
- {
- synchronized (cache)
- {
- Entry entry = cache.get(key);
- if(entry == null)
- throw new IllegalStateException("object " + key + " not from this cache");
- if(entry.state != EntryState.IN_USE)
- throw new IllegalStateException("entry " + entry + " is not in use");
- entry.state = EntryState.READY;
- entry.lastUsed = System.currentTimeMillis();
- }
- }
-
- public void remove(Object key)
- {
- Entry entry;
- synchronized (cache)
- {
- entry = cache.remove(key);
- if(entry.state != EntryState.READY)
- throw new IllegalStateException("entry " + entry + " is not ready");
- }
- if(entry != null)
- factory.destroy(entry.obj);
- }
-
- public void setName(String name)
- {
- this.name = name;
- }
-
- public void setSessionTimeout(int sessionTimeout)
- {
- assert sessionTimeout >= 0 : "sessionTimeout must be >= 0";
- this.sessionTimeout = sessionTimeout;
- }
-
- public void start()
- {
- assert name != null : "name has not been set";
- assert sessionTimeout != -1 : "sessionTimeout has not been set";
-
- if(sessionTimeout > 0)
- {
- sessionTimeoutTask = new SessionTimeoutThread("Passivation Thread - " + name);
- sessionTimeoutTask.start();
- }
- }
-
- public void stop()
- {
- if(sessionTimeoutTask != null)
- {
- sessionTimeoutTask.interrupt();
- try
- {
- sessionTimeoutTask.join(5000);
- }
- catch (InterruptedException e)
- {
- // ignore
- }
- if(sessionTimeoutTask.isAlive())
- log.warn("Failed to stop " + sessionTimeoutTask);
- }
- }
-
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache2.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache2.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SimplePassivatingCache2.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,220 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.cache.impl;
-
-import java.io.Serializable;
-
-import javax.ejb.NoSuchEJBException;
-
-import org.jboss.ejb3.cache.Cacheable;
-import org.jboss.ejb3.cache.IntegratedObjectStore;
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.PassivatingIntegratedObjectStore;
-import org.jboss.ejb3.cache.PassivationManager;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-import org.jboss.logging.Logger;
-
-/**
- * Non group-aware {@link PassivatingCache} that uses an {@link IntegratedObjectStore}
- * to manage data.
- *
- * @author Brian Stansberry
- * @version $Revision: 65339 $
- */
-public class SimplePassivatingCache2<T extends Cacheable & Serializable> implements PassivatingCache<T>
-{
- private static final Logger log = Logger.getLogger(SimplePassivatingCache2.class);
-
- private StatefulObjectFactory<T> factory;
- private PassivationManager<T> passivationManager;
- private IntegratedObjectStore<T> store;
-
- public SimplePassivatingCache2(StatefulObjectFactory<T> factory, PassivationManager<T> passivationManager, IntegratedObjectStore<T> store)
- {
- assert factory != null : "factory is null";
- assert passivationManager != null : "passivationManager is null";
- assert store != null : "store is null";
-
- this.factory = factory;
- this.passivationManager = passivationManager;
- this.store = store;
- if (store instanceof PassivatingIntegratedObjectStore)
- {
- ((PassivatingIntegratedObjectStore<T>) store).setPassivatingCache(this);
- }
- }
-
- public boolean isClustered()
- {
- return store.isClustered();
- }
-
- public void replicate(Object key)
- {
- if (!isClustered())
- {
- throw new UnsupportedOperationException("Clustering is not supported by " +
- store.getClass().getName());
- }
-
- log.trace("replicate " + key);
- synchronized (store)
- {
- T entry = store.get(key);
-
- if(entry == null)
- throw new IllegalArgumentException("entry " + key + " not found in cache " + this);
-
- if(entry.isInUse())
- {
- throw new IllegalStateException("entry " + entry + " is in use");
- }
-
- passivationManager.preReplicate(entry);
-
- store.update(entry);
- }
- }
-
- public T create(Class<?>[] initTypes, Object[] initValues)
- {
- T obj = factory.create(initTypes, initValues);
- obj.setInUse(true);
- synchronized (store)
- {
- store.insert(obj);
- }
- return obj;
- }
-
- public T get(Object key) throws NoSuchEJBException
- {
- synchronized (store)
- {
- T entry = store.get(key);
- if(entry == null)
- throw new NoSuchEJBException(String.valueOf(key));
-
- if (isClustered())
- {
- passivationManager.postReplicate(entry);
- }
-
- passivationManager.postActivate(entry);
-
-// if(entry.getCacheState() != Cacheable.State.READY)
-// {
-// throw new IllegalStateException("entry " + key + " is not ready");
-// }
- entry.setInUse(true);
- return entry;
- }
- }
-
- public void passivate(Object key)
- {
- log.trace("passivate " + key);
- synchronized (store)
- {
- T entry = store.get(key);
-
- if(entry == null)
- throw new IllegalArgumentException("entry " + key + " not found in cache " + this);
-
- if(entry.isInUse())
- {
- throw new IllegalStateException("entry " + entry + " is in use");
- }
-
- passivationManager.prePassivate(entry);
-
- store.passivate(entry);
- }
- }
-
- public T peek(Object key) throws NoSuchEJBException
- {
- synchronized (store)
- {
- T entry = store.get(key);
- if(entry == null)
- throw new NoSuchEJBException(String.valueOf(key));
-
- // TODO why call these in peek? We should *always* call
- // them in get() and let the PassivationManager sort out
- // whether they really need to be called
-
-// if (isClustered())
-// {
-// passivationManager.postReplicate(entry);
-// }
-//
-// passivationManager.postActivate(entry);
-
- return entry;
- }
- }
-
- public void release(T obj)
- {
- releaseByKey(obj.getId());
- }
-
- protected T releaseByKey(Object key)
- {
- synchronized (store)
- {
- T entry = store.get(key);
- if(entry == null)
- throw new IllegalStateException("object " + key + " not from this cache");
- if(!entry.isInUse())
- throw new IllegalStateException("entry " + entry + " is not in use");
- entry.setInUse(false);
- store.update(entry);
- return entry;
- }
- }
-
- public void remove(Object key)
- {
- T entry;
- synchronized (store)
- {
- entry = store.remove(key);
- if(entry.isInUse())
- throw new IllegalStateException("entry " + entry + " is in use");
- }
- if(entry != null)
- factory.destroy(entry);
- }
-
- public void start()
- {
- store.start();
- }
-
- public void stop()
- {
- store.stop();
- }
-
-}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/TransactionalCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,324 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.ejb.NoSuchEJBException;
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.SerializationGroup;
+import org.jboss.ejb3.cache.spi.BackingCache;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStore;
+
+/**
+ * {@link Cache#isGroupAware() Non-group-aware} <code>Cache</code> implementation
+ * that applies transactional access and release semantics. Specifically:
+ * <ol>
+ * <li>monitors the transactional status of threads that invoke create() and get()</li>
+ * <li>ensures that until the first transaction that accesses a given CacheItem
+ * has completed, any other transaction that attempts to access the item will
+ * receive an IllegalStateException</li>
+ * <li>Only releases the CacheItem to the underlying {@link IntegratedObjectStore}
+ * when the transaction commits or rolls back.</li>
+ * </ol>
+ * <p>
+ * Delegates many functions to a backing {@link BackingCache}.
+ * </p>
+ *
+ * @author Brian Stansberry
+ * @version $Revision: 69058 $
+ */
+public class TransactionalCache<C extends CacheItem, T extends BackingCacheEntry<C>> implements Cache<C>
+{
+ /** BackingCache that handles passivation, groups, etc */
+ private final BackingCache<C, T> delegate;
+
+ /** Cache of items that are in use by a tx or non-transactional invocation */
+ private final Map<Object, Entry> inUseCache;
+ /** Map of Synchronizations to release items in use by a tx*/
+ private final ConcurrentMap<Object, CacheReleaseSynchronization<C, T>> synchronizations;
+ /** Our transaction manager */
+ private final TransactionManager tm;
+
+ private enum State { INITIALIZED, IN_USE, FINISHED };
+ private class Entry
+ {
+ long lastUsed;
+ C obj;
+ State state;
+
+ Entry()
+ {
+ this.lastUsed = System.currentTimeMillis();
+ this.state = State.INITIALIZED;
+ }
+ }
+
+ private static class CacheReleaseSynchronization<C extends CacheItem, T extends BackingCacheEntry<C>>
+ implements Synchronization
+ {
+ private TransactionalCache<C, T> cache;
+ private C cacheItem;
+ private Transaction tx;
+
+ private CacheReleaseSynchronization(TransactionalCache<C, T> cache,
+ C cacheItem, Transaction tx)
+ {
+ assert cache != null : "cache is null";
+ assert cacheItem != null : "cacheItem is null";
+ assert tx != null : "tx is null";
+
+ this.cache = cache;
+ this.cacheItem = cacheItem;
+ this.tx = tx;
+ }
+
+ public Transaction getTransaction()
+ {
+ return tx;
+ }
+
+ public void beforeCompletion()
+ {
+ cache.release(cacheItem);
+ }
+
+ public void afterCompletion(int arg0)
+ {
+ cache.releaseSynchronization(cacheItem);
+ cache = null;
+ cacheItem = null;
+ tx = null;
+ }
+ }
+
+ public TransactionalCache(BackingCache<C, T> delegate, TransactionManager tm)
+ {
+ assert delegate != null : "delegate is null";
+ assert tm != null : "tm is null";
+
+ this.delegate = delegate;
+ this.tm = tm;
+
+ this.inUseCache = new HashMap<Object, Entry>();
+ this.synchronizations = new ConcurrentHashMap<Object, CacheReleaseSynchronization<C, T>>();
+ }
+
+ public C create(Class<?>[] initTypes, Object[] initValues)
+ {
+ T backingEntry = delegate.create(initTypes, initValues);
+ C obj = backingEntry.getUnderlyingItem();
+ synchronized (inUseCache)
+ {
+ // Create an entry, but do not store a ref to obj in the entry.
+ // This will ensure get() goes to the backingCache to get the
+ // missing obj, giving the backingCache an opportunity to mark
+ // the BackingCacheEntry as being in use
+ registerEntry(obj, false);
+ }
+ return obj;
+ }
+
+ private Entry registerEntry(C obj, boolean storeRef)
+ {
+ Entry entry = new Entry();
+ if (storeRef)
+ entry.obj = obj;
+ inUseCache.put(obj.getId(), entry);
+ registerSynchronization(obj);
+ return entry;
+ }
+
+ public C get(Object key) throws NoSuchEJBException
+ {
+ Entry entry = null;
+
+ // Yuck. This is a bottleneck
+ synchronized (inUseCache)
+ {
+ entry = inUseCache.get(key);
+ if(entry == null)
+ {
+ T backingEntry = delegate.get(key);
+ C obj = backingEntry.getUnderlyingItem();
+ entry = registerEntry(obj, true);
+ }
+ }
+
+ if (entry.obj == null)
+ entry.obj = delegate.get(key).getUnderlyingItem();
+
+ validateTransaction(entry.obj);
+ if(entry.state == State.IN_USE)
+ throw new IllegalStateException("entry " + key + " is already in use");
+ entry.state = State.IN_USE;
+ entry.lastUsed = System.currentTimeMillis();
+ return entry.obj;
+ }
+
+ public void finished(C obj)
+ {
+ Entry entry = null;
+ synchronized (inUseCache)
+ {
+ entry = inUseCache.get(obj.getId());
+ }
+ if (entry == null)
+ throw new IllegalStateException("No entry for " + obj.getId());
+ if(entry.state != State.IN_USE)
+ throw new IllegalStateException("entry " + obj.getId() + " is not in operation");
+ entry.state = State.FINISHED;
+ entry.lastUsed = System.currentTimeMillis();
+
+ // If there is no tx associated with this object, we can release it
+ if (synchronizations.get(obj.getId()) == null)
+ {
+ release(obj);
+ }
+
+ }
+
+ public void remove(Object key)
+ {
+ // Note that the object is not in my cache at this point.
+ // FIXME BES 2008/03/10 -- above comment not true!
+ delegate.remove(key);
+ inUseCache.remove(key);
+ }
+
+ public void start()
+ {
+ delegate.start();
+ }
+
+ public void stop()
+ {
+ delegate.stop();
+ }
+
+ public boolean isGroupAware()
+ {
+ return false;
+ }
+
+ public SerializationGroup<C> getGroup(C obj)
+ {
+ return null;
+ }
+
+ public BackingCache<C, T> getBackingCache()
+ {
+ return delegate;
+ }
+
+ /**
+ * Actually release the object from our delegate
+ * @param obj
+ */
+ private void release(C obj)
+ {
+ Object key = obj.getId();
+ synchronized (inUseCache)
+ {
+ Entry entry = inUseCache.get(key);
+ if (entry == null)
+ {
+ // FIXME is this correct?
+ return;
+ }
+ if(entry.state == State.IN_USE)
+ throw new IllegalStateException("entry " + key + " is not finished");
+ inUseCache.remove(key);
+ }
+ delegate.release(obj.getId());
+ }
+
+ private void registerSynchronization(C cacheItem)
+ {
+ Transaction tx = getCurrentTransaction();
+ if (tx != null)
+ {
+ CacheReleaseSynchronization<C, T> sync = new CacheReleaseSynchronization<C, T>(this, cacheItem, tx);
+ try
+ {
+ tx.registerSynchronization(sync);
+ }
+ catch (RollbackException e)
+ {
+ throw new RuntimeException("Failed registering synchronization for " + cacheItem, e);
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException("Failed registering synchronization for " + cacheItem, e);
+ }
+ synchronizations.put(cacheItem.getId(), sync);
+ }
+ }
+
+ private Transaction getCurrentTransaction()
+ {
+ try
+ {
+ return tm == null ? null : tm.getTransaction();
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException("Failed getting current transaction from " + tm, e);
+ }
+ }
+
+ private void releaseSynchronization(C cacheItem)
+ {
+ synchronizations.remove(cacheItem.getId());
+ }
+
+ private void validateTransaction(C cacheItem)
+ {
+ CacheReleaseSynchronization<C, T> sync = synchronizations.get(cacheItem.getId());
+
+ if (sync != null)
+ {
+ Transaction syncTx = sync.getTransaction();
+ if (syncTx != null) // may be null if sync has just completed
+ {
+ Transaction threadTx = getCurrentTransaction();
+ if(!syncTx.equals(threadTx))
+ {
+ throw new IllegalStateException("Illegal concurrent access to " + cacheItem +
+ " by two transactions: " + syncTx + " and " + threadTx);
+ }
+ }
+
+ }
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/GroupAwareBackingCacheImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.impl.backing;
+
+import javax.ejb.NoSuchEJBException;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.SerializationGroup;
+import org.jboss.ejb3.cache.spi.GroupAwareBackingCache;
+import org.jboss.ejb3.cache.spi.GroupIncompatibilityException;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+
+/**
+ * Group-aware version of {@link PassivatingBackingCacheImpl}.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class GroupAwareBackingCacheImpl<C extends CacheItem>
+ extends PassivatingBackingCacheImpl<C, SerializationGroupMember<C>>
+ implements GroupAwareBackingCache<C, SerializationGroupMember<C>>
+{
+ /**
+ * Cache that's managing the SerializationGroup
+ */
+ private PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache;
+
+ /**
+ * Creates a new GroupAwareCacheImpl.
+ *
+ * @param memberContainer the factory for the underlying CacheItems
+ * @param groupCache cache for the group
+ */
+ public GroupAwareBackingCacheImpl(SerializationGroupMemberContainer<C> memberContainer,
+ PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache)
+ {
+ super(memberContainer, memberContainer, memberContainer);
+ assert groupCache != null : "groupCache is null";
+ assert groupCache.isClustered() == memberContainer.isClustered(): "incompatible clustering support between groupCache and passivationManager";
+
+ this.groupCache = groupCache;
+ }
+
+ public SerializationGroupImpl<C> createGroup()
+ {
+ return groupCache.create(null, null);
+ }
+
+ public void setGroup(C obj, SerializationGroup<C> group) throws GroupIncompatibilityException
+ {
+ Object key = obj.getId();
+ SerializationGroupMember<C> entry = peek(key);
+ if(entry.getGroup() != null)
+ throw new IllegalStateException("object " + key + " is already associated with passivation group " + entry.getGroup());
+
+ // Validate we share a common groupCache with the group
+ SerializationGroupImpl<C> groupImpl = (SerializationGroupImpl<C>) group;
+ if (groupCache != groupImpl.getGroupCache())
+ throw new GroupIncompatibilityException(obj + " and " + groupImpl + " use different group caches");
+
+ entry.setGroup(groupImpl);
+ entry.getGroup().addMember(entry);
+ }
+
+ public SerializationGroup<C> getGroup(C obj)
+ {
+ Object key = obj.getId();
+ try
+ {
+ SerializationGroupMember<C> entry = peek(key);
+ return entry.getGroup();
+ }
+ catch (NoSuchEJBException nsee)
+ {
+ return null;
+ }
+ }
+
+
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheEntry.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheEntry.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheEntry.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.impl.backing;
+
+import java.io.Serializable;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.impl.AbstractBackingCacheEntry;
+
+/**
+ * Basic {@link BasicCacheEntry} implementation for use with a non-passivating
+ * {@link BackingCache}. A wrapper for the {@link CacheItem} to allow it to
+ * be managed by the backing cache .
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class NonPassivatingBackingCacheEntry<T extends CacheItem> extends AbstractBackingCacheEntry<T>
+ implements BackingCacheEntry<T>, Serializable
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 1325918596862109742L;
+
+ private T wrapped;
+
+ /**
+ * Create a new SimpleBackingCacheEntry.
+ *
+ * @param wrapped the item to wrap
+ */
+ public NonPassivatingBackingCacheEntry(T wrapped)
+ {
+ this.wrapped = wrapped;
+ }
+
+ // -------------------------------------------------------- BackingCacheEntry
+
+ public T getUnderlyingItem()
+ {
+ return wrapped;
+ }
+
+ public boolean isModified()
+ {
+ return wrapped.isModified();
+ }
+
+ public Object getId()
+ {
+ return wrapped.getId();
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/NonPassivatingBackingCacheImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,215 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.impl.backing;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.ejb.NoSuchEJBException;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+import org.jboss.ejb3.cache.spi.BackingCache;
+import org.jboss.ejb3.cache.spi.PassivationExpirationProcessor;
+import org.jboss.ejb3.cache.spi.impl.PassivationExpirationRunner;
+import org.jboss.logging.Logger;
+
+/**
+ * Simple {@link BackingCache} that doesn't handle passivation (although
+ * it does handle expiration). Pure in-VM memory cache. Not group-aware,
+ * as there is no point in managing groups if there is no serialization.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class NonPassivatingBackingCacheImpl<C extends CacheItem>
+ implements BackingCache<C, NonPassivatingBackingCacheEntry<C>>, PassivationExpirationProcessor
+{
+ private static final Logger log = Logger.getLogger(NonPassivatingBackingCacheImpl.class);
+
+ private StatefulObjectFactory<C> factory;
+ private Map<Object, NonPassivatingBackingCacheEntry<C>> cache;
+ private String name;
+ private long interval;
+ private int expirationTimeSeconds;
+ private PassivationExpirationRunner sessionTimeoutRunner;
+ private boolean stopped = true;
+
+ public NonPassivatingBackingCacheImpl(StatefulObjectFactory<C> factory)
+ {
+ assert factory != null;
+
+ this.factory = factory;
+ this.cache = new ConcurrentHashMap<Object, NonPassivatingBackingCacheEntry<C>>();
+ }
+
+ public NonPassivatingBackingCacheEntry<C> create(Class<?>[] initTypes, Object[] initValues)
+ {
+ C obj = factory.create(initTypes, initValues);
+ NonPassivatingBackingCacheEntry<C> entry = new NonPassivatingBackingCacheEntry<C>(obj);
+ cache.put(obj.getId(), entry);
+ return entry;
+ }
+
+ public NonPassivatingBackingCacheEntry<C> get(Object key) throws NoSuchEJBException
+ {
+ NonPassivatingBackingCacheEntry<C> entry = cache.get(key);
+ if(entry == null)
+ throw new NoSuchEJBException(String.valueOf(key));
+ if(entry.isInUse())
+ throw new IllegalStateException("entry " + entry + " is already in use");
+ entry.setInUse(true);
+ return entry;
+ }
+
+ public NonPassivatingBackingCacheEntry<C> peek(Object key) throws NoSuchEJBException
+ {
+ NonPassivatingBackingCacheEntry<C> entry = cache.get(key);
+ if(entry == null)
+ throw new NoSuchEJBException(String.valueOf(key));
+ return entry;
+ }
+
+ public NonPassivatingBackingCacheEntry<C> release(Object key)
+ {
+ NonPassivatingBackingCacheEntry<C> entry = cache.get(key);
+ if(entry == null)
+ throw new NoSuchEJBException(String.valueOf(key));
+ if(!entry.isInUse())
+ throw new IllegalStateException("entry " + key + " is not in use");
+ entry.setInUse(false);
+ return entry;
+ }
+
+ public void remove(Object key)
+ {
+ NonPassivatingBackingCacheEntry<C> entry = cache.remove(key);
+ if(entry != null && entry.isInUse())
+ entry.setInUse(false);
+ if(entry != null)
+ factory.destroy(entry.getUnderlyingItem());
+ }
+
+ public boolean isClustered()
+ {
+ return false;
+ }
+
+ public void start()
+ {
+ if (interval > 0)
+ {
+ if (sessionTimeoutRunner == null)
+ {
+ assert name != null : "name has not been set";
+ String timerName = "PassivationExpirationTimer-" + name;
+ sessionTimeoutRunner = new PassivationExpirationRunner(this, timerName, interval);
+ }
+ sessionTimeoutRunner.start();
+ }
+
+ stopped = false;
+
+ log.debug("Started " + name);
+ }
+
+ public void stop()
+ {
+ if (sessionTimeoutRunner != null)
+ {
+ sessionTimeoutRunner.stop();
+ }
+
+ stopped = true;
+
+ log.debug("Stopped " + name);
+ }
+
+ public long getInterval()
+ {
+ return interval;
+ }
+
+ public void setInterval(long interval)
+ {
+ this.interval = interval;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public int getExpirationTimeSeconds()
+ {
+ return expirationTimeSeconds;
+ }
+
+ public void setExpirationTimeSeconds(int expirationTimeSeconds)
+ {
+ this.expirationTimeSeconds = expirationTimeSeconds;
+ }
+
+ public boolean isPassivationExpirationSelfManaged()
+ {
+ return interval > 0;
+ }
+
+ public void processPassivationExpiration()
+ {
+ if (!stopped && expirationTimeSeconds > 0)
+ {
+ // FIXME -- this is totally brute force
+
+ long now = System.currentTimeMillis();
+ long minRemovalUse = now - (expirationTimeSeconds * 1000);
+ Set<NonPassivatingBackingCacheEntry<C>> entries = new HashSet<NonPassivatingBackingCacheEntry<C>>(cache.values());
+
+ for (NonPassivatingBackingCacheEntry<C> entry : entries)
+ {
+ if (!entry.isInUse() && minRemovalUse >= entry.getLastUsed())
+ {
+ try
+ {
+ remove(entry.getId());
+ }
+ catch (IllegalStateException ise)
+ {
+ // Not so great; we're assuming it's 'cause item's in use
+ log.trace("skipping in-use entry " + entry.getId(), ise);
+ }
+ }
+ }
+ }
+ }
+
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/PassivatingBackingCacheImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,183 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.impl.backing;
+
+import javax.ejb.NoSuchEJBException;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.PassivationManager;
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.logging.Logger;
+
+/**
+ * Non group-aware {@link PassivatingBackingCache} that uses a
+ * {@link PassivatingIntegratedObjectStore} to manage data.
+ *
+ * @author Brian Stansberry
+ * @version $Revision: 65339 $
+ */
+public class PassivatingBackingCacheImpl<C extends CacheItem, T extends BackingCacheEntry<C>>
+ implements PassivatingBackingCache<C, T>
+{
+ private static final Logger log = Logger.getLogger(PassivatingBackingCacheImpl.class);
+
+ private StatefulObjectFactory<T> factory;
+ private PassivationManager<T> passivationManager;
+ private PassivatingIntegratedObjectStore<C, T> store;
+
+ public PassivatingBackingCacheImpl(StatefulObjectFactory<T> factory,
+ PassivationManager<T> passivationManager,
+ PassivatingIntegratedObjectStore<C, T> store)
+ {
+ assert factory != null : "factory is null";
+ assert passivationManager != null : "passivationManager is null";
+ assert store != null : "store is null";
+
+ this.factory = factory;
+ this.passivationManager = passivationManager;
+ this.store = store;
+ this.store.setPassivatingCache(this);
+ }
+
+ public boolean isClustered()
+ {
+ return store.isClustered();
+ }
+
+ public T create(Class<?>[] initTypes, Object[] initValues)
+ {
+ T obj = factory.create(initTypes, initValues);
+// obj.setInUse(true);
+ synchronized (store)
+ {
+ store.insert(obj);
+ }
+ return obj;
+ }
+
+ public T get(Object key) throws NoSuchEJBException
+ {
+ synchronized (store)
+ {
+ T entry = store.get(key);
+ if(entry == null)
+ throw new NoSuchEJBException(String.valueOf(key));
+
+ if(entry.isInUse())
+ {
+ throw new IllegalStateException("entry " + entry + " is in use");
+ }
+
+ if (isClustered())
+ {
+ passivationManager.postReplicate(entry);
+ }
+
+ passivationManager.postActivate(entry);
+
+ entry.setInUse(true);
+ return entry;
+ }
+ }
+
+ public void passivate(Object key)
+ {
+ log.trace("passivate " + key);
+ synchronized (store)
+ {
+ T entry = store.get(key);
+
+ if(entry == null)
+ throw new IllegalArgumentException("entry " + key + " not found in cache " + this);
+
+ if(entry.isInUse())
+ {
+ throw new IllegalStateException("entry " + entry + " is in use");
+ }
+
+ passivationManager.prePassivate(entry);
+
+ store.passivate(entry);
+ }
+ }
+
+ public T peek(Object key) throws NoSuchEJBException
+ {
+ synchronized (store)
+ {
+ T entry = store.get(key);
+ if(entry == null)
+ throw new NoSuchEJBException(String.valueOf(key));
+ return entry;
+ }
+ }
+
+ public T release(Object key)
+ {
+ synchronized (store)
+ {
+ T entry = store.get(key);
+ if(entry == null)
+ throw new IllegalStateException("object " + key + " not from this cache");
+ if(!entry.isInUse())
+ throw new IllegalStateException("entry " + entry + " is not in use");
+ entry.setInUse(false);
+
+ if (entry.isModified())
+ {
+ if (isClustered())
+ {
+ passivationManager.preReplicate(entry);
+ }
+ store.update(entry);
+ }
+
+ return entry;
+ }
+ }
+
+ public void remove(Object key)
+ {
+ T entry;
+ synchronized (store)
+ {
+ entry = store.remove(key);
+ if(entry != null && entry.isInUse())
+ entry.setInUse(false);
+ }
+ if(entry != null)
+ factory.destroy(entry);
+ }
+
+ public void start()
+ {
+ store.start();
+ }
+
+ public void stop()
+ {
+ store.stop();
+ }
+}
Copied: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java (from rev 70283, projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupContainer.java)
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupContainer.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,112 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.impl.backing;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.PassivationManager;
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.logging.Logger;
+
+/**
+ * Comment
+ *
+ * FIXME determine whether SerializationGroup clustering support should
+ * be controlled by a property of this container or via a param passed
+ * to create().
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @author Brian Stansberry
+ * @version $Revision: $
+ */
+public class SerializationGroupContainer<T extends CacheItem>
+ implements StatefulObjectFactory<SerializationGroupImpl<T>>, PassivationManager<SerializationGroupImpl<T>>
+{
+ private static final Logger log = Logger.getLogger(SerializationGroupContainer.class);
+
+ private PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache;
+
+ private boolean clustered;
+
+ public boolean isClustered()
+ {
+ return clustered;
+ }
+
+ public void setClustered(boolean clustered)
+ {
+ this.clustered = clustered;
+ }
+
+ public SerializationGroupImpl<T> create(Class<?>[] initTypes, Object[] initValues)
+ {
+ SerializationGroupImpl<T> group = new SerializationGroupImpl<T>();
+ group.setClustered(clustered);
+ group.setGroupCache(groupCache);
+ return group;
+ }
+
+ public void destroy(SerializationGroupImpl<T> group)
+ {
+ // TODO: nothing?
+ }
+
+ public void postActivate(SerializationGroupImpl<T> group)
+ {
+ log.trace("post activate " + group);
+ // Restore ref to the groupCache in case it was lost during serialization
+ group.setGroupCache(groupCache);
+ group.postActivate();
+ }
+
+ public void prePassivate(SerializationGroupImpl<T> group)
+ {
+ log.trace("pre passivate " + group);
+ group.prePassivate();
+ }
+
+ public void postReplicate(SerializationGroupImpl<T> group)
+ {
+ log.trace("post replicate " + group);
+ // Restore ref to the groupCache in case it was lost during serialization
+ group.setGroupCache(groupCache);
+ group.postReplicate();
+ }
+
+ public void preReplicate(SerializationGroupImpl<T> group)
+ {
+ log.trace("pre replicate " + group);
+ group.preReplicate();
+ }
+
+ public PassivatingBackingCache<T, SerializationGroupImpl<T>> getGroupCache()
+ {
+ return groupCache;
+ }
+
+ public void setGroupCache(PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache)
+ {
+ this.groupCache = groupCache;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SerializationGroupMemberContainer.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,323 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.impl.backing;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.PassivationManager;
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+import org.jboss.logging.Logger;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class SerializationGroupMemberContainer<C extends CacheItem>
+ implements StatefulObjectFactory<SerializationGroupMember<C>>,
+ PassivationManager<SerializationGroupMember<C>>,
+ PassivatingIntegratedObjectStore<C, SerializationGroupMember<C>>
+{
+ private static final Logger log = Logger.getLogger(SerializationGroupMemberContainer.class);
+
+ private StatefulObjectFactory<C> factory;
+ private PassivationManager<C> passivationManager;
+ private PassivatingIntegratedObjectStore<C, SerializationGroupMember<C>> store;
+ private PassivatingBackingCache<C, SerializationGroupMember<C>> delegate;
+
+ /**
+ * Cache that's managing the PassivationGroup
+ */
+ private PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache;
+
+
+ public SerializationGroupMemberContainer(StatefulObjectFactory<C> factory,
+ PassivationManager<C> passivationManager,
+ PassivatingIntegratedObjectStore<C, SerializationGroupMember<C>> store,
+ PassivatingBackingCache<C, SerializationGroupImpl<C>> groupCache)
+ {
+ assert factory != null : "factory is null";
+ assert passivationManager != null : "passivationManager is null";
+ assert store != null : "store is null";
+ assert groupCache != null : "groupCache is null";
+
+ this.factory = factory;
+ this.passivationManager = passivationManager;
+ this.store = store;
+ this.groupCache = groupCache;
+ }
+
+ public SerializationGroupMember<C> create(Class<?>[] initTypes, Object[] initValues)
+ {
+ SerializationGroupMember<C> member =
+ new SerializationGroupMember<C>(factory.create(initTypes, initValues),
+ delegate);
+ return member;
+ }
+
+ public void destroy(SerializationGroupMember<C> entry)
+ {
+ factory.destroy(entry.getUnderlyingItem());
+ SerializationGroupImpl<C> group = entry.getGroup();
+ if (group != null)
+ {
+ group.removeMember(entry.getId());
+ if (group.size() == 0)
+ {
+ groupCache.remove(group.getId());
+ }
+ }
+ }
+
+ public void postActivate(SerializationGroupMember<C> entry)
+ {
+ log.trace("post activate " + entry);
+
+ // Restore the entry's ref to the group and object
+ SerializationGroupImpl<C> group = entry.getGroup();
+ if(group == null && entry.getGroupId() != null)
+ {
+ // TODO: peek or get?
+ // BES 2007/10/06 I think peek is better; no
+ // sense marking the group as in-use and then having
+ // to release it or something
+ group = groupCache.peek(entry.getGroupId());
+ entry.setGroup(group);
+ }
+
+ if(group != null)
+ {
+ entry.setUnderlyingItem(group.getMemberObject(entry.getId()));
+
+ // Notify the group that this entry is active
+ group.addActive(entry);
+ }
+
+ // Invoke callbacks on the underlying object
+ if (entry.isPrePassivated())
+ {
+ passivationManager.postActivate(entry.getUnderlyingItem());
+ entry.setPrePassivated(false);
+ }
+ }
+
+ public void prePassivate(SerializationGroupMember<C> entry)
+ {
+ log.trace("pre-passivate " + entry);
+
+ // entry.obj may or may not get serialized (depends on if group
+ // is in use) but it's ok to invoke callbacks now. If a caller
+ // requests this entry again and the obj hadn't been serialized with
+ // the group, we'll just call postActivate on it then, which is OK.
+ if (!entry.isPrePassivated())
+ {
+ passivationManager.prePassivate(entry.getUnderlyingItem());
+ entry.setPrePassivated(true);
+ }
+
+ // If this call is coming via PassivatingBackingCache.passivate(),
+ // entry.group will *not* be null. In that case we are the controller
+ // for the group passivation. If the call is coming via entry.prePassivate(),
+ // entry.group *will* be null. In that case we are not the controller
+ // of the passivation and can just return.
+ SerializationGroupImpl<C> group = entry.getGroup();
+ if(group != null)
+ {
+ synchronized (group)
+ {
+ if (!group.isInvalid())
+ {
+ // Remove ourself from group's active list so we don't get
+ // called again via entry.prePassivate()
+ group.removeActive(entry.getId());
+
+ // Only tell the group to passivate if no members are in use
+ if (group.getInUseCount() == 0)
+ {
+ // Go ahead and do the real passivation.
+ groupCache.passivate(group.getId());
+ group.setInvalid(true);
+ }
+ // else {
+ // this turns into a pretty meaningless exercise of just
+ // passivating an empty entry. TODO consider throwing
+ // ItemInUseException here, thus aborting everything. Need to
+ // be sure that doesn't lead to problems as the exception propagates
+ // }
+
+ // This call didn't come through entry.prePassivate() (which nulls
+ // group and obj) so we have to do it ourselves. Otherwise
+ // when this call returns, delegate will serialize the entry
+ // with a ref to group and obj.
+ entry.setGroup(null);
+ entry.setUnderlyingItem(null);
+ }
+ }
+ }
+ }
+
+ public void preReplicate(SerializationGroupMember<C> entry)
+ {
+ // This method follows the same conceptual logic as prePassivate.
+ // See the detailed comments in that method.
+
+ log.trace("pre-replicate " + entry);
+
+ if (!entry.isPreReplicated())
+ {
+ passivationManager.preReplicate(entry.getUnderlyingItem());
+ entry.setPreReplicated(true);
+ }
+
+ SerializationGroupImpl<C> group = entry.getGroup();
+ if(group != null)
+ {
+ // Remove ourself from group's active list so we don't get
+ // called again via entry.prePassivate()
+ group.removeActive(entry.getId());
+
+ try
+ {
+ if (group.getInUseCount() == 0)
+ {
+// group.preReplicate();
+ groupCache.release(group);
+ }
+ }
+ finally
+ {
+ // Here we differ from prePassivate!!
+ // Restore the entry as "active" so it can get
+ // passivation callbacks
+ group.addActive(entry);
+ }
+
+// entry.setGroup(null);
+// entry.setUnderlyingItem(null);
+ }
+ }
+
+ public void postReplicate(SerializationGroupMember<C> entry)
+ {
+ log.trace("postreplicate " + entry);
+
+ // Restore the entry's ref to the group and object
+ SerializationGroupImpl<C> group = entry.getGroup();
+ if(group == null && entry.getGroupId() != null)
+ {
+ // TODO: peek or get?
+ // BES 2007/10/06 peek is better; you'll get multiple calls to
+ // this as different members are accessed, and the cache
+ // will throw an ISE if we use get() since we're already in use
+ group = groupCache.peek(entry.getGroupId());
+ entry.setGroup(group);
+ }
+
+ if(group != null)
+ {
+ entry.setUnderlyingItem(group.getMemberObject(entry.getId()));
+
+ // Notify the group that this entry is active
+ group.addActive(entry);
+ }
+
+ // Invoke callbacks on the underlying object
+ if (entry.isPreReplicated())
+ {
+ passivationManager.postReplicate(entry.getUnderlyingItem());
+ entry.setPreReplicated(false);
+ }
+ }
+
+ public void update(SerializationGroupMember<C> entry)
+ {
+ store.update(entry);
+ }
+
+ public boolean isClustered()
+ {
+ return groupCache.isClustered();
+ }
+
+ public SerializationGroupMember<C> get(Object key)
+ {
+ SerializationGroupMember<C> entry = store.get(key);
+ // In case it was deserialized, make sure it has a ref to us
+ if (entry != null)
+ entry.setPassivatingCache(delegate);
+ return entry;
+ }
+
+ public void passivate(SerializationGroupMember<C> entry)
+ {
+ store.passivate(entry);
+ }
+
+ public void insert(SerializationGroupMember<C> entry)
+ {
+ store.insert(entry);
+ }
+
+ public SerializationGroupMember<C> remove(Object key)
+ {
+ return store.remove(key);
+ }
+
+ public void start()
+ {
+ store.start();
+ }
+
+ public void stop()
+ {
+ store.stop();
+ }
+
+ public int getInterval()
+ {
+ return store.getInterval();
+ }
+
+ public void setInterval(int seconds)
+ {
+ store.setInterval(seconds);
+ }
+
+ public void setPassivatingCache(PassivatingBackingCache<C, SerializationGroupMember<C>> cache)
+ {
+ this.delegate= cache;
+ this.store.setPassivatingCache(delegate);
+ }
+
+ public boolean isPassivationExpirationSelfManaged()
+ {
+ return store.isPassivationExpirationSelfManaged();
+ }
+
+ public void processPassivationExpiration()
+ {
+ store.processPassivationExpiration();
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/backing/SimplePassivatingIntegratedObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,354 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.impl.backing;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.ObjectStore;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.impl.CacheableTimestamp;
+import org.jboss.ejb3.cache.spi.impl.PassivationExpirationRunner;
+import org.jboss.logging.Logger;
+
+/**
+ * A {@link PassivatingIntegratedObjectStore} that stores in a simple
+ * <code>Map</code> and delegates to a provided {@link ObjectStore} for
+ * persistence.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class SimplePassivatingIntegratedObjectStore<C extends CacheItem, T extends BackingCacheEntry<C>>
+ implements PassivatingIntegratedObjectStore<C, T>
+{
+ private static final Logger log = Logger.getLogger(SimplePassivatingIntegratedObjectStore.class);
+
+ private final ObjectStore<T> store;
+ private Map<Object, T> cache;
+ private Map<Object, Long> passivatedEntries;
+
+ /**
+ * Support callbacks when our SessionTimeoutThread decides to
+ * evict an entry.
+ */
+ private PassivatingBackingCache<C, T> owningCache;
+ private int interval;
+ private int maxSize;
+ private long idleTimeSeconds;
+ private long expirationTimeSeconds;
+ private PassivationExpirationRunner sessionTimeoutRunner;
+ private String name;
+ private boolean stopped = true;
+
+ /**
+ * Create a new SimpleIntegratedObjectStore.
+ */
+ public SimplePassivatingIntegratedObjectStore(ObjectStore<T> store,
+ CacheConfig config,
+ String name)
+ {
+ assert store != null : "store is null";
+ assert config != null : "config is null";
+ assert name != null : "name is null";
+
+ this.store = store;
+ this.cache = new HashMap<Object, T>();
+ this.passivatedEntries = new HashMap<Object, Long>();
+ this.idleTimeSeconds = config.idleTimeoutSeconds();
+ this.expirationTimeSeconds = config.removalTimeoutSeconds();
+ this.maxSize = config.maxSize();
+ this.name = name;
+ }
+
+ public boolean isClustered()
+ {
+ return false;
+ }
+
+ public T get(Object key)
+ {
+ synchronized (cache)
+ {
+ T entry = cache.get(key);
+ if(entry == null)
+ {
+ entry = store.load(key);
+ if(entry != null)
+ {
+ cache.put(key, entry);
+ passivatedEntries.remove(key);
+ }
+ }
+ return entry;
+ }
+ }
+
+ public void insert(T entry)
+ {
+ Object key = entry.getId();
+ synchronized (cache)
+ {
+ if (cache.containsKey(key) || passivatedEntries.containsKey(key))
+ {
+ throw new IllegalStateException(key + " is already in store");
+ }
+ cache.put(key, entry);
+ }
+ }
+
+ public void update(T entry)
+ {
+ Object key = entry.getId();
+ synchronized (cache)
+ {
+ if (!cache.containsKey(key) && !passivatedEntries.containsKey(key))
+ {
+ throw new IllegalStateException(key + " is not managed by this store");
+ }
+
+ // Otherwise we do nothing; we already have a ref to the entry
+ }
+ }
+
+ public void passivate(T entry)
+ {
+ synchronized (cache)
+ {
+ Object key = entry.getId();
+ store.store(entry);
+ passivatedEntries.put(key, new Long(entry.getLastUsed()));
+ cache.remove(key);
+ }
+ }
+
+ public T remove(Object id)
+ {
+ synchronized (cache)
+ {
+ T entry = get(id);
+ if (entry != null)
+ {
+ cache.remove(id);
+ }
+ return entry;
+ }
+ }
+
+ public void start()
+ {
+ store.start();
+
+ if (interval > 0)
+ {
+ if (sessionTimeoutRunner == null)
+ {
+ assert name != null : "name has not been set";
+ assert owningCache != null;
+ String timerName = "PassivationExpirationTimer-" + name;
+ sessionTimeoutRunner = new PassivationExpirationRunner(this, timerName, interval);
+ }
+ sessionTimeoutRunner.start();
+ }
+
+ stopped = false;
+
+ log.debug("Started " + name);
+ }
+
+ public void stop()
+ {
+ store.stop();
+
+ if (sessionTimeoutRunner != null)
+ {
+ sessionTimeoutRunner.stop();
+ }
+
+ stopped = true;
+
+ log.debug("Stopped " + name);
+ }
+
+ // --------------------------------------- PassivatingIntegratedObjectStore
+
+
+ public void setPassivatingCache(PassivatingBackingCache<C, T> cache)
+ {
+ this.owningCache = cache;
+ }
+
+ public int getInterval()
+ {
+ return interval;
+ }
+
+ public void setInterval(int seconds)
+ {
+ this.interval = seconds;
+ }
+
+ public void processPassivationExpiration()
+ {
+ if (!stopped)
+ {
+ try
+ {
+ runPassivation();
+ }
+ catch (Exception e)
+ {
+ log.error("Caught exception processing passivations", e);
+ }
+ }
+ if (!stopped)
+ {
+ try
+ {
+ runExpiration();
+ }
+ catch (Exception e)
+ {
+ log.error("Caught exception processing expirations", e);
+ }
+ }
+ }
+
+ public boolean isPassivationExpirationSelfManaged()
+ {
+ return interval > 0;
+ }
+
+ private void runExpiration()
+ {
+ if (expirationTimeSeconds > 0)
+ {
+ long now = System.currentTimeMillis();
+ long minRemovalUse = now - (expirationTimeSeconds * 1000);
+ for (CacheableTimestamp ts : getPassivatedEntries())
+ {
+ try
+ {
+ if (minRemovalUse >= ts.getLastUsed())
+ {
+ remove(ts.getId());
+ }
+ }
+ catch (IllegalStateException ise)
+ {
+ // Not so great; we're assuming it's 'cause item's in use
+ log.trace("skipping in-use entry " + ts.getId(), ise);
+ }
+ }
+ }
+ }
+
+ private void runPassivation()
+ {
+ if (idleTimeSeconds > 0)
+ {
+ long now = System.currentTimeMillis();
+ long minPassUse = now - (idleTimeSeconds * 1000);
+
+ // Scan the in-memory entries for passivation or removal
+ SortedSet<CacheableTimestamp> timestamps = getInMemoryEntries();
+ int overCount = timestamps.size() - maxSize;
+ for (CacheableTimestamp ts : timestamps)
+ {
+ try
+ {
+ long lastUsed = ts.getLastUsed();
+ if (overCount > 0 || minPassUse >= lastUsed)
+ {
+ synchronized (cache)
+ {
+ T entry = cache.get(ts.getId());
+ if (entry == null || entry.isInUse())
+ continue;
+ }
+ owningCache.passivate(ts.getId());
+ overCount--;
+ }
+ }
+ catch (IllegalStateException ise)
+ {
+ // Not so great; we're assuming it's 'cause item's in use
+ log.trace("skipping in-use entry " + ts.getId(), ise);
+ }
+ }
+ }
+
+ }
+
+ public int getMaxSize()
+ {
+ return maxSize;
+ }
+
+ public long getIdleTimeSeconds()
+ {
+ return idleTimeSeconds;
+ }
+
+ public void setIdleTimeSeconds(long idleTimeSeconds)
+ {
+ this.idleTimeSeconds = idleTimeSeconds;
+ }
+
+ public long getExpirationTimeSeconds()
+ {
+ return expirationTimeSeconds;
+ }
+
+ public void setExpirationTimeSeconds(long timeout)
+ {
+ this.expirationTimeSeconds = timeout;
+ }
+
+ private SortedSet<CacheableTimestamp> getInMemoryEntries()
+ {
+ SortedSet<CacheableTimestamp> set = new TreeSet<CacheableTimestamp>();
+ for (Map.Entry<Object, T> entry : cache.entrySet())
+ {
+ set.add(new CacheableTimestamp(entry.getKey(), entry.getValue().getLastUsed()));
+ }
+ return set;
+ }
+
+ private SortedSet<CacheableTimestamp> getPassivatedEntries()
+ {
+ SortedSet<CacheableTimestamp> set = new TreeSet<CacheableTimestamp>();
+ for (Map.Entry<Object, Long> entry : passivatedEntries.entrySet())
+ {
+ set.add(new CacheableTimestamp(entry.getKey(), entry.getValue().longValue()));
+ }
+ return set;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/GroupAwareCacheFactory.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,138 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.impl.factory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.PassivationManager;
+import org.jboss.ejb3.cache.StatefulCacheFactory;
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+import org.jboss.ejb3.cache.impl.GroupAwareTransactionalCache;
+import org.jboss.ejb3.cache.impl.backing.GroupAwareBackingCacheImpl;
+import org.jboss.ejb3.cache.impl.backing.PassivatingBackingCacheImpl;
+import org.jboss.ejb3.cache.impl.backing.SerializationGroupContainer;
+import org.jboss.ejb3.cache.impl.backing.SerializationGroupMemberContainer;
+import org.jboss.ejb3.cache.spi.GroupAwareBackingCache;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.impl.AbstractStatefulCacheFactory;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+
+/**
+ * {@link StatefulCacheFactory} implementation that can return a group-aware
+ * cache. How the cache functions depends on the behavior of the
+ * {@link PassivatingIntegratedObjectStore} implementations returned by
+ * the injected {@link IntegratedObjectStoreSource}.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class GroupAwareCacheFactory<T extends CacheItem>
+ extends AbstractStatefulCacheFactory<T>
+{
+ private final Map<String, PassivatingBackingCache<T, SerializationGroupImpl<T>>> groupCaches;
+ private final IntegratedObjectStoreSource<T> storeSource;
+
+ /**
+ * Creates a new GroupAwareCacheFactory that gets its object stores from
+ * the provided source.
+ */
+ public GroupAwareCacheFactory(IntegratedObjectStoreSource<T> storeSource)
+ {
+ assert storeSource != null : "storeSource is null";
+
+ this.storeSource = storeSource;
+ this.groupCaches = new HashMap<String, PassivatingBackingCache<T, SerializationGroupImpl<T>>>();
+ }
+
+ // --------------------------------------------------- StatefulCacheFactory
+
+ public Cache<T> createCache(String containerName,
+ StatefulObjectFactory<T> factory,
+ PassivationManager<T> passivationManager, CacheConfig cacheConfig)
+ {
+ String configName = getCacheConfigName(cacheConfig);
+
+ PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache = groupCaches.get(configName);
+ if (groupCache == null)
+ {
+ groupCache = createGroupCache(containerName, configName, cacheConfig);
+ groupCaches.put(configName, groupCache);
+ }
+
+ PassivatingIntegratedObjectStore<T, SerializationGroupMember<T>> store =
+ storeSource.createIntegratedObjectStore(containerName, configName, cacheConfig, getTransactionManager());
+
+ // Make sure passivation/expiration occurs periodically
+ if (store.getInterval() < 1)
+ {
+ if (getPassivationExpirationCoordinator() != null)
+ {
+ // Let our coordinator manage this
+ getPassivationExpirationCoordinator().addPassivationExpirationProcessor(store);
+ }
+ else
+ {
+ // Tell the store to manage this itself, using our default interval
+ store.setInterval(getDefaultPassivationExpirationInterval());
+ }
+ }
+ // else the store is configured to manage processing itself
+
+ SerializationGroupMemberContainer<T> memberContainer =
+ new SerializationGroupMemberContainer<T>(factory, passivationManager, store, groupCache);
+
+ GroupAwareBackingCache<T, SerializationGroupMember<T>> backingCache =
+ new GroupAwareBackingCacheImpl<T>(memberContainer, groupCache);
+
+ return new GroupAwareTransactionalCache<T, SerializationGroupMember<T>>(backingCache, getTransactionManager());
+ }
+
+ private PassivatingBackingCache<T, SerializationGroupImpl<T>> createGroupCache(String name, String configName, CacheConfig cacheConfig)
+ {
+ SerializationGroupContainer<T> container = new SerializationGroupContainer<T>();
+ StatefulObjectFactory<SerializationGroupImpl<T>> factory = container;
+ PassivationManager<SerializationGroupImpl<T>> passivationManager = container;
+ PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> store =
+ storeSource.createGroupIntegratedObjectStore(name, configName, cacheConfig, getTransactionManager());
+
+ // The group cache store should not passivate/expire -- that's a
+ // function of the caches for the members
+ store.setInterval(0);
+
+ PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache =
+ new PassivatingBackingCacheImpl<T, SerializationGroupImpl<T>>(factory, passivationManager, store);
+
+ container.setGroupCache(groupCache);
+
+ groupCache.start();
+
+ return groupCache;
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonClusteredIntegratedObjectStoreSource.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,189 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.impl.factory;
+
+import java.io.File;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.impl.backing.SimplePassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.impl.FileObjectStore;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+
+/**
+ * {@link IntegratedObjectStoreSource} for a non-clustered cache. Uses
+ * a {@link FileObjectStore} store for persistence.
+ *
+ * @author Brian Stansberry
+ */
+public class NonClusteredIntegratedObjectStoreSource<T extends CacheItem>
+ implements IntegratedObjectStoreSource<T>
+{
+ /**
+ * The default session store directory name ("<tt>ejb3/sessions</tt>").
+ */
+ String DEFAULT_SESSION_DIRECTORY_NAME = "ejb3" + File.separatorChar + "sessions";
+
+ /**
+ * The default session group store directory name ("<tt>ejb3/sfsbgroups</tt>").
+ */
+ String DEFAULT_GROUP_DIRECTORY_NAME = "ejb3" + File.separatorChar + "sfsbgroups";
+
+ public static final int DEFAULT_SUBDIRECTORY_COUNT = 100;
+
+ private String sessionDirectoryName = DEFAULT_SESSION_DIRECTORY_NAME;
+ private String groupDirectoryName = DEFAULT_GROUP_DIRECTORY_NAME;
+ private String baseDirectoryName;
+ private int subdirectoryCount = DEFAULT_SUBDIRECTORY_COUNT;
+
+ public PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> createGroupIntegratedObjectStore(String containerName, String cacheConfigName,
+ CacheConfig cacheConfig, TransactionManager transactionManager)
+ {
+ FileObjectStore<SerializationGroupImpl<T>> objectStore = new FileObjectStore<SerializationGroupImpl<T>>();
+ objectStore.setStorageDirectory(getFullGroupDirectoryName(containerName));
+ objectStore.setSubdirectoryCount(subdirectoryCount);
+
+ String storeName = "StdGroupStore-"+cacheConfig.name();
+ SimplePassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> store =
+ new SimplePassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>>(objectStore, cacheConfig, storeName);
+
+ return store;
+ }
+
+ public PassivatingIntegratedObjectStore<T, SerializationGroupMember<T>> createIntegratedObjectStore(String containerName, String cacheConfigName,
+ CacheConfig cacheConfig, TransactionManager transactionManager)
+ {
+ FileObjectStore<SerializationGroupMember<T>> objectStore = new FileObjectStore<SerializationGroupMember<T>>();
+ objectStore.setStorageDirectory(getFullSessionDirectoryName(containerName));
+ objectStore.setSubdirectoryCount(subdirectoryCount);
+
+ SimplePassivatingIntegratedObjectStore<T, SerializationGroupMember<T>> store =
+ new SimplePassivatingIntegratedObjectStore<T, SerializationGroupMember<T>>(objectStore, cacheConfig, containerName);
+
+ return store;
+ }
+
+ protected String getFullSessionDirectoryName(String containerName)
+ {
+ File base = new File(getBaseDirectoryName());
+ File child = new File(base, getSessionDirectoryName());
+ File full = new File(child, containerName);
+ return full.getAbsolutePath();
+ }
+
+ protected String getFullGroupDirectoryName(String containerName)
+ {
+ File base = new File(getBaseDirectoryName());
+ File child = new File(base, getGroupDirectoryName());
+ File full = new File(child, containerName);
+ return full.getAbsolutePath();
+ }
+
+ /**
+ * Gets the name of the base directory under which sessions and
+ * groups should be stored. Default is the java.io.tmpdir.
+ */
+ public synchronized String getBaseDirectoryName()
+ {
+ if (baseDirectoryName == null)
+ {
+ setBaseDirectoryName(System.getProperty("java.io.tmpdir"));
+ }
+ return baseDirectoryName;
+ }
+
+ /**
+ * Sets the name of the base directory under which sessions and
+ * groups should be stored.
+ */
+ public void setBaseDirectoryName(String baseDirectoryName)
+ {
+ this.baseDirectoryName = baseDirectoryName;
+ }
+
+ /**
+ * Gets the name of the subdirectory under the
+ * {@link #getBaseDirectoryName() base directory} under which sessions
+ * should be stored. Default is {@link #DEFAULT_SESSION_DIRECTORY_NAME}.
+ */
+ public String getSessionDirectoryName()
+ {
+ return sessionDirectoryName;
+ }
+
+ /**
+ * Sets the name of the subdirectory under the
+ * {@link #getBaseDirectoryName() base directory} under which sessions
+ * should be stored.
+ */
+ public void setSessionDirectoryName(String directoryName)
+ {
+ this.sessionDirectoryName = directoryName;
+ }
+
+ /**
+ * Gets the name of the subdirectory under the
+ * {@link #getBaseDirectoryName() base directory} under which session groups
+ * should be stored. Default is {@link #DEFAULT_GROUP_DIRECTORY_NAME}.
+ */
+ public String getGroupDirectoryName()
+ {
+ return groupDirectoryName;
+ }
+
+ /**
+ * Sets the name of the subdirectory under the
+ * {@link #getBaseDirectoryName() base directory} under which session groups
+ * should be stored.
+ */
+ public void setGroupDirectoryName(String groupDirectoryName)
+ {
+ this.groupDirectoryName = groupDirectoryName;
+ }
+
+ /**
+ * Gets the number of subdirectories under the session directory or the
+ * group directory into which the sessions/groups should be divided. Using
+ * subdirectories helps overcome filesystem limits on the number of items
+ * that can be stored. Default is {@link #DEFAULT_SUBDIRECTORY_COUNT}.
+ */
+ public int getSubdirectoryCount()
+ {
+ return subdirectoryCount;
+ }
+
+ /**
+ * Sets the number of subdirectories under the session directory or the
+ * group directory into which the sessions/groups should be divided.
+ */
+ public void setSubdirectoryCount(int subdirectoryCount)
+ {
+ this.subdirectoryCount = subdirectoryCount;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/NonPassivatingCacheFactory.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.impl.factory;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.PassivationManager;
+import org.jboss.ejb3.cache.StatefulCacheFactory;
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+import org.jboss.ejb3.cache.impl.TransactionalCache;
+import org.jboss.ejb3.cache.impl.backing.NonPassivatingBackingCacheEntry;
+import org.jboss.ejb3.cache.impl.backing.NonPassivatingBackingCacheImpl;
+import org.jboss.ejb3.cache.spi.impl.AbstractStatefulCacheFactory;
+
+/**
+ * {@link StatefulCacheFactory} implementation that will return a
+ * {@link Cache#isGroupAware() non-group-aware} cache that doesn't support
+ * passivation.
+ *
+ * @author Brian Stansberry
+ */
+public class NonPassivatingCacheFactory<T extends CacheItem>
+ extends AbstractStatefulCacheFactory<T>
+{
+
+ public Cache<T> createCache(String containerName,
+ StatefulObjectFactory<T> factory,
+ PassivationManager<T> passivationManager,
+ CacheConfig config)
+ {
+ NonPassivatingBackingCacheImpl<T> backingCache = new NonPassivatingBackingCacheImpl<T>(factory);
+ backingCache.setName(containerName);
+
+ // Make sure passivation/expiration occurs periodically
+ if (getPassivationExpirationCoordinator() != null)
+ {
+ // Let our coordinator manage this
+ getPassivationExpirationCoordinator().addPassivationExpirationProcessor(backingCache);
+ }
+ else
+ {
+ // Tell the store to manage this itself, using our default interval
+ backingCache.setInterval(getDefaultPassivationExpirationInterval());
+ }
+
+ return new TransactionalCache<T, NonPassivatingBackingCacheEntry<T>>(backingCache, getTransactionManager());
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/PassivationExpirationCoordinatorImpl.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/PassivationExpirationCoordinatorImpl.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/factory/PassivationExpirationCoordinatorImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,220 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.impl.factory;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+
+import org.jboss.ejb3.cache.spi.PassivationExpirationCoordinator;
+import org.jboss.ejb3.cache.spi.PassivationExpirationProcessor;
+import org.jboss.ejb3.cache.spi.impl.AbstractTimerTask;
+import org.jboss.util.threadpool.BasicThreadPool;
+
+/**
+ * {@link PassivationExpirationCoordinator} implementation that runs as a
+ * background TimerTask which when executed takes threads from a thread
+ * pool and uses them to process passivation and expiration.
+ * <p>
+ * If no thread pool is provided, the passivation/expiration will be handled
+ * by the timer thread itself.
+ * </p>
+ *
+ * @author Brian Stansberry
+ */
+public class PassivationExpirationCoordinatorImpl
+ extends AbstractTimerTask
+ implements PassivationExpirationCoordinator
+{
+ public static final long DEFAULT_INTERVAL = 10000L;
+ public static final String TIMER_NAME = "EJB3SFSBPassivationExpirationCoordinator";
+
+ private BasicThreadPool threadPool;
+ private int maxPoolThreads;
+ private Set<PassivationExpirationProcessor> processors = new HashSet<PassivationExpirationProcessor>();
+ private Semaphore threadLimit;
+
+ public PassivationExpirationCoordinatorImpl()
+ {
+ super(TIMER_NAME, DEFAULT_INTERVAL);
+ }
+
+ // -------------------------------------------------------------- Properties
+
+ /**
+ * Gets the thread pool used to get threads for concurrently processing
+ * passivation/expiration on different caches.
+ *
+ * @return the pool. May be <code>null</code>
+ */
+ public BasicThreadPool getThreadPool()
+ {
+ return threadPool;
+ }
+
+ /**
+ * Sets the thread pool to use to get threads for concurrently processing
+ * passivation/expiration on different caches.
+ *
+ * @param threadPool the pool. May be <code>null</code>
+ */
+ public void setThreadPool(BasicThreadPool threadPool)
+ {
+ this.threadPool = threadPool;
+ }
+
+ /**
+ * Gets the maximum number of threads that can be concurrently taken from the
+ * {@link #getThreadPool() thread pool} in order to process
+ * passivation/expiration on different caches.
+ *
+ * @return the maximum number of threads. A value less than 1 means
+ * the thread pool will not be used.
+ */
+ public int getMaxPoolThreads()
+ {
+ return maxPoolThreads;
+ }
+
+ /**
+ * Sets the maximum number of threads to concurrently take from the
+ * {@link #getThreadPool() thread pool} in order to process
+ * passivation/expiration on different caches.
+ *
+ * @param numThreads the maximum number of threads. A value less than
+ * 1 disables use of the thread pool.
+ */
+ public void setMaxPoolThreads(int numThreads)
+ {
+ this.maxPoolThreads = numThreads;
+ }
+
+ // ---------------------------------------- PassivationExpirationCoordinator
+
+ public void addPassivationExpirationProcessor(PassivationExpirationProcessor processor)
+ {
+ synchronized (processors)
+ {
+ processors.add(processor);
+ }
+ }
+
+ public void removePassivationExpirationProcessor(PassivationExpirationProcessor processor)
+ {
+ synchronized (processors)
+ {
+ processors.remove(processor);
+ }
+ }
+
+ // -------------------------------------------------------------- TimerTask
+
+ @Override
+ public void run()
+ {
+ while (!isStopped())
+ {
+ Set<PassivationExpirationProcessor> toProcess = new HashSet<PassivationExpirationProcessor>();
+ synchronized (processors)
+ {
+ toProcess.addAll(processors);
+ }
+
+ for (PassivationExpirationProcessor cache : toProcess)
+ {
+ if (cache.isPassivationExpirationSelfManaged())
+ continue;
+
+ PassivationExpirationTask task = new PassivationExpirationTask(cache, threadLimit);
+ if (threadLimit != null)
+ {
+ // Limit the number of concurrent threads
+ try
+ {
+ threadLimit.acquire();
+ }
+ catch (InterruptedException ignore)
+ {
+ }
+
+ if (isStopped())
+ break;
+
+ threadPool.run(task);
+ }
+ else
+ {
+ // We run it our self
+ task.run();
+ }
+
+
+ if (isStopped())
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void start()
+ {
+ if (isStopped())
+ {
+ if (threadPool != null && getMaxPoolThreads() > 0)
+ {
+ threadLimit = new Semaphore(getMaxPoolThreads());
+ }
+ }
+ super.start();
+ }
+
+ /**
+ * Task executed by the thread pool thread.
+ */
+ private class PassivationExpirationTask implements Runnable
+ {
+ private final PassivationExpirationProcessor cache;
+ private final Semaphore semaphore;
+
+ PassivationExpirationTask(PassivationExpirationProcessor cache, Semaphore semaphore)
+ {
+ assert cache != null : "cache is null";
+ assert semaphore != null : "semaphore is null";
+
+ this.cache = cache;
+ this.semaphore = semaphore;
+ }
+
+ public void run()
+ {
+ try
+ {
+ cache.processPassivationExpiration();
+ }
+ finally
+ {
+ semaphore.release();
+ }
+ }
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+import javax.ejb.NoSuchEJBException;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.CacheItem;
+
+/**
+ * An internal cache to which an external-facing {@link Cache} delegates, either
+ * directly or indirectly.
+ * <p>
+ * The key distinction between a BackingCache and the external-facing Cache is
+ * that a Cache directly handles external classes that implement the
+ * limited {@link CacheItem} interface. CacheItem is deliberately limited to
+ * avoid placing a implementation burden on external classes. A BackingCache
+ * works with instances of the more expressive internal interface
+ * {@link BackingCacheEntry}, and thus can directly implement more complex
+ * functionality.
+ * </p>
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public interface BackingCache<C extends CacheItem, T extends BackingCacheEntry<C>>
+{
+ /**
+ * Creates and caches a new instance of <code>T</code>. The new
+ * <code>T</code> *is* returned, but is not regarded as being "in use".
+ * Callers *must not* attempt to use the underlying <code>C</code> without
+ * first calling {@link #get(Object)}.
+ *
+ * @param initTypes the types of any <code>initValues</code>.
+ * May be <code>null</code>.
+ * @param initValues any paramaters to pass to <code>T</code>'s constructor.
+ * May be null, in which case a default constructor will
+ * be used.
+ * @return the new <code>T</code>
+ */
+ T create(Class<?> initTypes[], Object initValues[]);
+
+ /**
+ * Get the specified object from cache. This will mark
+ * the object as being in use.
+ *
+ * @param key the identifier of the object
+ * @return the object
+ * @throws NoSuchEJBException if the object does not exist
+ */
+ T get(Object key) throws NoSuchEJBException;
+
+ /**
+ * Peek at an object which might be in use.
+ *
+ * @param key the identifier of the object
+ * @return the object
+ * @throws NoSuchEJBException if the object does not exist
+ */
+ T peek(Object key) throws NoSuchEJBException;
+
+ /**
+ * Release the object from use.
+ *
+ * @param key the identifier of the object
+ *
+ * @return the entry that was released
+ */
+ T release(Object key);
+
+ /**
+ * Remove the specified object from cache.
+ *
+ * @param key the identifier of the object
+ */
+ void remove(Object key);
+
+ /**
+ * Start the cache.
+ */
+ void start();
+
+ /**
+ * Stop the cache.
+ */
+ void stop();
+
+ /**
+ * Gets whether this cache supports clustering functionality.
+ *
+ * @return <code>true</code> if clustering is supported, <code>false</code>
+ * otherwise
+ */
+ boolean isClustered();
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCacheEntry.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCacheEntry.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/BackingCacheEntry.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.CacheItem;
+
+
+/**
+ * An object that can be managed by a {@link BackingCache}.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public interface BackingCacheEntry<T extends CacheItem>
+ extends CacheItem
+{
+ /**
+ * Gets the underlying object that should be serialized as part of
+ * serialization of the group.
+ *
+ * @return
+ */
+ T getUnderlyingItem();
+
+ /**
+ * Gets whether this object is in use by a caller.
+ */
+ boolean isInUse();
+
+ /**
+ * Sets whether this object is in use by a caller.
+ *
+ * @param inUse
+ */
+ void setInUse(boolean inUse);
+
+ /**
+ * Gets the timestamp of the last time this object was in use.
+ *
+ * @return
+ */
+ long getLastUsed();
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupAwareBackingCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.SerializationGroup;
+
+/**
+ * A {@link BackingCache} that can manage the relationship of its
+ * underlying entries to any {@link SerializationGroup}.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public interface GroupAwareBackingCache<C extends CacheItem, T extends BackingCacheEntry<C>>
+ extends PassivatingBackingCache<C, T>
+{
+ /**
+ * Create a {@link SerializationGroup} to contain objects cached by
+ * this object.
+ *
+ * @return a {@link SerializationGroup}
+ */
+ SerializationGroup<C> createGroup();
+
+ /**
+ * Assign the given object to the given group. The group will be
+ * of the {@link SerializationGroup} implementation type returned
+ * by {@link #createGroup()}.
+ *
+ * @param obj
+ * @param group
+ *
+ * @throws GroupIncompatibilityException if the group's cache is incompatible
+ * with ourself.
+ */
+ void setGroup(C obj, SerializationGroup<C> group) throws GroupIncompatibilityException;
+
+ /**
+ * Gets the group the given object is a member of
+ *
+ * @param obj the object
+ * @return the group, or <code>null</code> if the object is not a member
+ * of a group
+ */
+ SerializationGroup<C> getGroup(C obj);
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupIncompatibilityException.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupIncompatibilityException.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/GroupIncompatibilityException.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class GroupIncompatibilityException extends Exception
+{
+
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 8202720497027287887L;
+
+ /**
+ * Create a new IncompatibleGroupException.
+ *
+ * @param message
+ */
+ public GroupIncompatibilityException(String message)
+ {
+ super(message);
+ }
+
+}
Copied: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStore.java (from rev 70283, projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/IntegratedObjectStore.java)
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStore.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,112 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.Identifiable;
+
+/**
+ * An in-memory store for identifiable objects that integrates a persistent store.
+ * Note that this class does NOT call any callbacks.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public interface IntegratedObjectStore<T extends CacheItem>
+{
+ /**
+ * Put a new entry into the store. This operation should only be
+ * performed once per entry.
+ *
+ * @param entry the object to store. Cannot be <code>null</code>.
+ *
+ * @throws IllegalStateException if the store is already managing an entry
+ * with the same {@link Identifiable#getId() id}.
+ * It is not a requirement that the store throw
+ * this exception in this case, but it is
+ * permissible. This basically puts the onus on
+ * callers to ensure this operation is only
+ * performed once per entry.
+ */
+ void insert(T entry);
+
+ /**
+ * Gets the entry with the given id from the store.
+ *
+ * @param key {@link Identifiable#getId() id} of the entry.
+ * Cannot be <code>null</code>.
+ * @return the object store under <code>id</code>. May return <code>null</code>.
+ */
+ T get(Object key);
+
+ /**
+ * Update an already cached item.
+ *
+ * @param entry the entry to update
+ *
+ * @throws IllegalStateException if the store isn't already managing an entry
+ * with the same {@link Identifiable#getId() id}.
+ * It is not a requirement that the store throw
+ * this exception in this case, but it is
+ * permissible. This basically puts the onus on
+ * callers to ensure {@link #insert(Cacheable)}
+ * is invoked before the first replication.
+ */
+ void update(T entry);
+
+ /**
+ * Remove the object with the given key from the store.
+ *
+ * @param key {@link Identifiable#getId() id} of the entry.
+ * Cannot be <code>null</code>.
+ *
+ * @return the object that was cached under <code>key</code>
+ */
+ T remove(Object key);
+
+ /**
+ * Remove the entry with the given key from any in-memory store
+ * while retaining it in the persistent store.
+ *
+ * @param entry the entry to passivate
+ */
+ void passivate(T entry);
+
+ /**
+ * Gets whether this store supports clustering functionality.
+ *
+ * @return <code>true</code> if clustering is supported, <code>false</code>
+ * otherwise
+ */
+ boolean isClustered();
+
+ /**
+ * Perform any initialization work.
+ */
+ void start();
+
+ /**
+ * Perform any shutdown work.
+ */
+ void stop();
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/IntegratedObjectStoreSource.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,76 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.StatefulCacheFactory;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+
+/**
+ * Provides {@link PassivatingIntegratedObjectStore} instances to a
+ * {@link StatefulCacheFactory} that needs to create a
+ * {@link GroupAwareBackingCache}.
+ *
+ * @author Brian Stansberry
+ */
+public interface IntegratedObjectStoreSource<T extends CacheItem>
+{
+ /**
+ * Provide a {@link PassivatingIntegratedObjectStore} for storage
+ * of serialization groups.
+ *
+ * @param containerName name of the container using this store's cache
+ * @param cacheConfigName potentially aliased name of the cache configuration.
+ * Implementations should use this value in place
+ * of {@link CacheConfig#name()}
+ * @param config configuration details of the cache
+ * @param transactionManager TransactionManager the store should use if
+ * it needs to monitor transactions
+ * @return the store
+ */
+ PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>>
+ createGroupIntegratedObjectStore(String containerName,
+ String cacheConfigName,
+ CacheConfig config,
+ TransactionManager transactionManager);
+
+ /**
+ * Provide a {@link PassivatingIntegratedObjectStore} for storage
+ * of serialization group members.
+ *
+ * @param containerName name of the container using this store's cache
+ * @param cacheConfigName TODO
+ * @param transactionManager TransactionManager the store should use if
+ * it needs to monitor transactions
+ * @param config configuration details of the cache
+ * @return the store
+ */
+ PassivatingIntegratedObjectStore<T, SerializationGroupMember<T>>
+ createIntegratedObjectStore(String containerName,
+ String cacheConfigName,
+ CacheConfig cacheConfig, TransactionManager transactionManager);
+}
Copied: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/ObjectStore.java (from rev 70283, projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/ObjectStore.java)
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/ObjectStore.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/ObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.CacheItem;
+
+
+/**
+ * Stores an indentifiable object in a persistent store. Note that the object store
+ * does NOT call any callbacks.
+ *
+ * It is assumed the key represents something meaning full to the object store.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public interface ObjectStore<T extends CacheItem>
+{
+ /**
+ * Load the object from storage.
+ *
+ * @param key the object identifier
+ * @return the object or null if not found
+ */
+ T load(Object key);
+
+ /**
+ * Store the object into storage.
+ *
+ * @param obj the object
+ */
+ void store(T obj);
+
+ /**
+ * Perform any initialization work.
+ */
+ void start();
+
+ /**
+ * Perform any shutdown work.
+ */
+ void stop();
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingBackingCache.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+
+
+/**
+ * A {@link BackingCache} which passivates unused objects.
+ *
+ * A PassivatingCache is linked to an ObjectStore to store the
+ * passivated object and a PassivationManager to manage lifecycle
+ * callbacks on the object.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: 65977 $
+ */
+public interface PassivatingBackingCache<C extends CacheItem, T extends BackingCacheEntry<C>>
+ extends BackingCache<C, T>
+{
+ /**
+ * Force passivation of an object. The object must not be in use.
+ *
+ * @param key the identifier of the object
+ *
+ * @throws IllegalStateException if the object, or another object in the
+ * same {@link SerializationGroupImpl} as the object,
+ * is in use.
+ */
+ void passivate(Object key);
+}
Copied: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingIntegratedObjectStore.java (from rev 70283, projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/PassivatingIntegratedObjectStore.java)
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingIntegratedObjectStore.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivatingIntegratedObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.CacheItem;
+
+/**
+ * An {@link IntegratedObjectStore} that is able to use its knowledge of
+ * when objects are accessed to coordinate the passivation and removal of
+ * cached objects.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public interface PassivatingIntegratedObjectStore<C extends CacheItem, T extends BackingCacheEntry<C>>
+ extends IntegratedObjectStore<T>, PassivationExpirationProcessor
+{
+ /**
+ * Gets how often, in seconds, this object should process
+ * {@link #runPassivation() passivations} and
+ * {@link #runExpiration() expirations}.
+ *
+ * @return interval, in seconds, at which passivations and expirations
+ * are processed. A value of less than 1 means this object will
+ * not itself initiate processing, depending instead on an external
+ * caller to do so.
+ */
+ int getInterval();
+
+ /**
+ * Sets how often, in seconds, this object should process
+ * {@link #runPassivation() passivations} and
+ * {@link #runExpiration() expirations}.
+ *
+ * @param seconds interval, in seconds, at which passivations and
+ * expirations should be processed. A value of less than 1
+ * means this object will not itself initiate processing,
+ * depending instead on an external caller to do so.
+ */
+ void setInterval(int seconds);
+
+ /**
+ * Handback provided by the controlling {@link PassivatingBackingCache} to
+ * allow the actual {@link PassivatingBackingCache#passivate(Object) passivate}
+ * and {@link Cache#remove(Object) remove} calls.
+ *
+ * @param cache
+ */
+ void setPassivatingCache(PassivatingBackingCache<C, T> cache);
+
+ // TODO determine what the standard configurations are
+
+// int getPassivationTimeout();
+// void setPassivationTimeout(int timeout);
+//
+// int getRemovalTimeout();
+// void setRemovalTimeout(int timeout);
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationCoordinator.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationCoordinator.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationCoordinator.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+/**
+ * Object that coordinates the execution of the
+ * {@link PassivationExpirationProcessor#processPassivationExpiration() passivation and expiration process}
+ * for a set of {@link PassivationExpirationProcessor} instances.
+ *
+ * @author Brian Stansberry
+ *
+ */
+public interface PassivationExpirationCoordinator
+{
+ /**
+ * Add a processor to the set managed by this coordinator.
+ *
+ * @param processor the processor. Cannot be <code>null</code>.
+ */
+ void addPassivationExpirationProcessor(PassivationExpirationProcessor processor);
+
+ /**
+ * Remove a processor from the set managed by this coordinator.
+ *
+ * @param processor the processor. Cannot be <code>null</code>.
+ */
+ void removePassivationExpirationProcessor(PassivationExpirationProcessor processor);
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationProcessor.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationProcessor.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/PassivationExpirationProcessor.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi;
+
+/**
+ * An object that can process passivation and expiration of cache entries.
+ *
+ * @author Brian Stansberry
+ */
+public interface PassivationExpirationProcessor
+{
+ /**
+ * Tells the processor to analyze its current content, passivating or expiring
+ * any items that meet its rules for passivation or expiration. This method
+ * provides a hook for an external background cleanup thread to trigger
+ * passivation and expiration. This method should not be invoked if
+ * {@link #isPassivationExpirationSelfManaged() the cache is managing its
+ * own background process} for this.
+ */
+ void processPassivationExpiration();
+
+ /**
+ * Gets whether this cache is running its own background process to trigger
+ * passivation and expiration.
+ *
+ * @return <code>true</code> if the cache is managing its own background
+ * process; <code>false</code> otherwise.
+ */
+ boolean isPassivationExpirationSelfManaged();
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractBackingCacheEntry.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractBackingCacheEntry.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractBackingCacheEntry.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.spi.impl;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+
+/**
+ * Abstract superclass for {@link BackingCacheEntry} implementations.
+ *
+ * @author Brian Stansberry
+ *
+ * @param <T>
+ */
+public abstract class AbstractBackingCacheEntry<T extends CacheItem>
+ implements BackingCacheEntry<T>
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 4562025672441864736L;
+
+ private long lastUsed;
+ private transient boolean inUse;
+
+ public long getLastUsed()
+ {
+ return lastUsed;
+ }
+
+ public boolean isInUse()
+ {
+ return inUse;
+ }
+
+ public void setInUse(boolean inUse)
+ {
+ this.inUse = inUse;
+ setLastUsed(System.currentTimeMillis());
+ }
+
+ protected void setLastUsed(long lastUsed)
+ {
+ this.lastUsed = lastUsed;
+ }
+
+}
\ No newline at end of file
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractStatefulCacheFactory.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,171 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi.impl;
+
+import java.util.Map;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.StatefulCacheFactory;
+import org.jboss.ejb3.cache.spi.PassivationExpirationCoordinator;
+
+/**
+ * Abstract superclass of {@link StatefulCacheFactory} implementations.
+ *
+ * @author Brian Stansberry
+ */
+public abstract class AbstractStatefulCacheFactory<T extends CacheItem>
+ implements StatefulCacheFactory<T>
+{
+ public static final int DEFAULT_PASSIVATION_EXPIRATION_INTERVAL = 10;
+
+ private TransactionManager transactionManager;
+ private PassivationExpirationCoordinator passivationExpirationCoordinator;
+ private int defaultPassivationExpirationInterval = DEFAULT_PASSIVATION_EXPIRATION_INTERVAL;
+ private String defaultCacheConfigName;
+ private Map<String, String> cacheConfigAliases;
+
+ // ------------------------------------------------------------- Properties
+
+ /**
+ * Gets the transaction manager to be used by the caches.
+ */
+ public TransactionManager getTransactionManager()
+ {
+ return transactionManager;
+ }
+
+ /**
+ * Sets the transaction manager to be used by the caches. Must be
+ * set for caching to work.
+ */
+ public void setTransactionManager(TransactionManager transactionManager)
+ {
+ this.transactionManager = transactionManager;
+ }
+
+ /**
+ * Gets the coordinator of passivation/expiration processes. If
+ * <code>null</code>, each cache will manager passivation/expiration
+ * with their own thread.
+ *
+ * @return the coordinator. May be <code>null</code>.
+ */
+ public PassivationExpirationCoordinator getPassivationExpirationCoordinator()
+ {
+ return passivationExpirationCoordinator;
+ }
+
+ /**
+ * Sets the coordinator of passivation/expiration processes.
+ */
+ public void setPassivationExpirationCoordinator(PassivationExpirationCoordinator coordinator)
+ {
+ this.passivationExpirationCoordinator = coordinator;
+ }
+
+ /**
+ * Gets the interval at which passivation/expiration tasks will execute
+ * if no {@link PassivationExpirationCoordinator} is provided.
+ *
+ * @return the interval, in seconds
+ */
+ public int getDefaultPassivationExpirationInterval()
+ {
+ return defaultPassivationExpirationInterval;
+ }
+
+ /**
+ * Sets the interval at which passivation/expiration tasks will execute
+ * if no {@link PassivationExpirationCoordinator} is provided.
+ *
+ * @param interval the interval, in seconds
+ */
+ public void setDefaultPassivationExpirationInterval(int interval)
+ {
+ this.defaultPassivationExpirationInterval = interval;
+ }
+
+ /**
+ * Gets the value to internally substitute for {@link CacheConfig#name()}
+ * if that attribute returns an empty string.
+ *
+ * @return the substitute value. May be <code>null</code>
+ */
+ public String getDefaultCacheConfigName()
+ {
+ return defaultCacheConfigName;
+ }
+
+ /**
+ * Sets the value to internally substitute for {@link CacheConfig#name()}
+ * if that attribute returns an empty string.
+ */
+ public void setDefaultCacheConfigName(String defaultCacheConfigName)
+ {
+ this.defaultCacheConfigName = defaultCacheConfigName;
+ }
+
+ /**
+ * Gets a map of substitute (alias) values for {@link CacheConfig#name()}
+ * values. Map key is the {@link CacheConfig#name()}, value is the substitute
+ * name to use instead.
+ *
+ * @return the aliases. May be <code>null</code>.
+ */
+ public Map<String, String> getCacheConfigAliases()
+ {
+ return cacheConfigAliases;
+ }
+
+ /**
+ * Sets a map of substitute (alias) values for {@link CacheConfig#name()}
+ * values. Map key is the {@link CacheConfig#name()}, value is the substitute
+ * name to use instead.
+ */
+ public void setCacheConfigAliases(Map<String, String> cacheConfigAliases)
+ {
+ this.cacheConfigAliases = cacheConfigAliases;
+ }
+
+ // ----------------------------------------------------------------- Public
+
+ public String getCacheConfigName(CacheConfig cacheConfig)
+ {
+ String name = cacheConfig.name();
+ String substitute = null;
+ if (cacheConfigAliases != null)
+ {
+ substitute = cacheConfigAliases.get(name);
+ }
+ if (substitute == null && name.length() == 0)
+ {
+ substitute = defaultCacheConfigName;
+ }
+
+ return substitute == null ? name : substitute;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractTimerTask.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractTimerTask.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/AbstractTimerTask.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi.impl;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Abstract superclass of various TimerTask implementations.
+ *
+ * @author Brian Stansberry
+ */
+public abstract class AbstractTimerTask
+ extends TimerTask
+{
+ private boolean stopped = true;
+ private Timer timer;
+ private String timerName;
+ private long interval;
+
+ /**
+ * Create a new PassivationExpirationRunner.
+ *
+ */
+ protected AbstractTimerTask(String timerName, long interval)
+ {
+ setTimerName(timerName);
+ setInterval(interval);
+ }
+
+ protected AbstractTimerTask() {}
+
+ public boolean isStopped()
+ {
+ return stopped;
+ }
+
+ public Timer getTimer()
+ {
+ return timer;
+ }
+
+ public String getTimerName()
+ {
+ return timerName;
+ }
+
+ public void setTimerName(String name)
+ {
+ assert name != null : "name is null";
+ this.timerName = name;
+ }
+
+ /**
+ * Gets the interval, in milliseconds, with which this task should
+ * be {@link Timer#schedule(TimerTask, long) scheduled with the timer}.
+ *
+ * @return the interval
+ */
+ public long getInterval()
+ {
+ return interval;
+ }
+
+ /**
+ * Sets the interval, in milliseconds, with which this task should
+ * be {@link Timer#schedule(TimerTask, long) scheduled with the timer}.
+ *
+ * @param interval the interval
+ */
+ public void setInterval(long interval)
+ {
+ assert interval > 0 : "interval is < 1";
+ this.interval = interval;
+ }
+
+ public void start()
+ {
+ if (stopped)
+ {
+ timer = new Timer(getTimerName(), true);
+ stopped = false;
+ long period = getInterval() * 1000;
+ timer.schedule(this, period, period);
+ }
+ }
+
+ public void stop()
+ {
+ stopped = true;
+ cancel();
+ timer.cancel();
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/CacheableTimestamp.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,100 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi.impl;
+
+import org.jboss.ejb3.cache.Identifiable;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStore;
+
+/**
+ * Encapsulation of the {@link Identifiable#getId() id} and
+ * {@link BackingCacheEntry#getLastUsed() last used timestamp} of
+ * a cached {@link BackingCacheEntry}.
+ * <p>
+ * Implements <code>Comparable</code> to make it easy to sort
+ * for LRU comparisons.
+ * </p>
+ *
+ * @see IntegratedObjectStore#getInMemoryEntries()
+ * @see IntegratedObjectStore#getPassivatedEntries()
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class CacheableTimestamp
+ implements Identifiable, Comparable<CacheableTimestamp>
+{
+ private Object id;
+ private long lastUsed;
+
+ public CacheableTimestamp(Object id, long lastUsed)
+ {
+ assert id != null : "id cannot be null";
+ assert lastUsed > 0 : "lastUsed must be positive";
+
+ this.id = id;
+ this.lastUsed = lastUsed;
+ }
+
+ public Object getId()
+ {
+ return id;
+ }
+
+ public long getLastUsed()
+ {
+ return lastUsed;
+ }
+
+ /**
+ * Compares based on {@link #getLastUsed() last used}, returning
+ * -1 for earlier timestamps.
+ */
+ public int compareTo(CacheableTimestamp o)
+ {
+ if (this.lastUsed < o.lastUsed)
+ return -1;
+ else if (this.lastUsed > o.lastUsed)
+ return 1;
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+
+ if (obj instanceof CacheableTimestamp)
+ {
+ return this.id.equals(((CacheableTimestamp) obj).id);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return id.hashCode();
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/FileObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/FileObjectStore.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/FileObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,283 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.spi.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.ObjectStore;
+import org.jboss.logging.Logger;
+import org.jboss.serial.io.JBossObjectInputStream;
+import org.jboss.serial.io.JBossObjectOutputStream;
+
+/**
+ * Stores objects in a directory via serialization.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: 65339 $
+ */
+public class FileObjectStore<T extends CacheItem>
+ implements ObjectStore<T>
+{
+ private static final Logger log = Logger.getLogger(FileObjectStore.class);
+
+ private int subdirectoryCount;
+ private File baseDirectory;
+ private File[] storageDirectories;
+
+ private static class DeleteFileAction implements PrivilegedAction<Boolean>
+ {
+ File file;
+
+ DeleteFileAction(File file)
+ {
+ this.file = file;
+ }
+
+ public Boolean run()
+ {
+ return file.delete();
+ }
+
+ static boolean delete(File file)
+ {
+ DeleteFileAction action = new DeleteFileAction(file);
+ return AccessController.doPrivileged(action);
+ }
+ }
+
+ private static class FISAction implements PrivilegedExceptionAction<FileInputStream>
+ {
+ File file;
+
+ FISAction(File file)
+ {
+ this.file = file;
+ }
+
+ public FileInputStream run() throws FileNotFoundException
+ {
+ FileInputStream fis = new FileInputStream(file);
+ return fis;
+ }
+
+ static FileInputStream open(File file) throws FileNotFoundException
+ {
+ FISAction action = new FISAction(file);
+ FileInputStream fis = null;
+ try
+ {
+ fis = AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw (FileNotFoundException) e.getException();
+ }
+ return fis;
+ }
+ }
+
+ private static class FOSAction implements PrivilegedExceptionAction<FileOutputStream>
+ {
+ File file;
+
+ FOSAction(File file)
+ {
+ this.file = file;
+ }
+
+ public FileOutputStream run() throws FileNotFoundException
+ {
+ FileOutputStream fis = new FileOutputStream(file);
+ return fis;
+ }
+
+ static FileOutputStream open(File file) throws FileNotFoundException
+ {
+ FOSAction action = new FOSAction(file);
+ FileOutputStream fos = null;
+ try
+ {
+ fos = AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException e)
+ {
+ throw (FileNotFoundException) e.getException();
+ }
+ return fos;
+ }
+ }
+
+ private static class MkdirsFileAction implements PrivilegedAction<Boolean>
+ {
+ File file;
+
+ MkdirsFileAction(File file)
+ {
+ this.file = file;
+ }
+
+ public Boolean run()
+ {
+ return file.mkdirs();
+ }
+
+ static boolean mkdirs(File file)
+ {
+ MkdirsFileAction action = new MkdirsFileAction(file);
+ return AccessController.doPrivileged(action);
+ }
+ }
+
+ protected File getFile(Object key)
+ {
+ File base = null;
+ if (storageDirectories != null)
+ {
+ int hash = Math.abs(key.hashCode()) % storageDirectories.length;
+ base = storageDirectories[hash];
+ }
+ else
+ {
+ base = baseDirectory;
+ }
+ return new File(base, String.valueOf(key) + ".ser");
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public T load(Object key)
+ {
+ File file = getFile(key);
+ if(!file.exists())
+ return null;
+
+ log.debug("loading state from " + file);
+ try
+ {
+ FileInputStream fis = FISAction.open(file);
+ ObjectInputStream in = new JBossObjectInputStream(fis);
+// ObjectInputStream in = new ObjectInputStream(fis);
+ try
+ {
+ return (T) in.readObject();
+ }
+ finally
+ {
+ in.close();
+ DeleteFileAction.delete(file);
+ }
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new RuntimeException("failed to load object " + key, e);
+ }
+ catch(IOException e)
+ {
+ throw new RuntimeException("failed to load object " + key, e);
+ }
+ }
+
+ public void setStorageDirectory(String dirName)
+ {
+ baseDirectory = new File(dirName);
+ }
+
+ public void setSubdirectoryCount(int subdirectoryCount)
+ {
+ this.subdirectoryCount = subdirectoryCount;
+ }
+
+ public void start()
+ {
+ assert baseDirectory != null : "baseDirectory is null";
+ assert subdirectoryCount > 0 : "subdirectoryCount is < 1";
+
+ establishDirectory(baseDirectory);
+
+ if (subdirectoryCount > 1)
+ {
+ storageDirectories = new File[subdirectoryCount];
+ for (int i = 0; i < storageDirectories.length; i++)
+ {
+ File f = new File(baseDirectory, String.valueOf(i));
+ establishDirectory(f);
+ storageDirectories[i] = f;
+ }
+ }
+ }
+
+ private void establishDirectory(File dir)
+ {
+ if(!dir.exists())
+ {
+ if(!MkdirsFileAction.mkdirs(dir))
+ throw new RuntimeException("Unable to create storage directory " + dir);
+ dir.deleteOnExit();
+ }
+
+ if(!dir.isDirectory())
+ throw new RuntimeException("Storage directory " + dir + " is not a directory");
+
+ }
+
+ public void stop()
+ {
+ // TODO: implement
+ }
+
+ public void store(T obj)
+ {
+ File file = getFile(obj.getId());
+ file.deleteOnExit();
+ log.debug("saving state to " + file);
+ try
+ {
+ FileOutputStream fos = FOSAction.open(file);
+ ObjectOutputStream out = new JBossObjectOutputStream(fos);
+// ObjectOutputStream out = new ObjectOutputStream(fos);
+ try
+ {
+ out.writeObject(obj);
+ out.flush();
+ }
+ finally
+ {
+ out.close();
+ }
+ }
+ catch(IOException e)
+ {
+ throw new RuntimeException("failed to store object " + obj.getId(), e);
+ }
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/PassivationExpirationRunner.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/PassivationExpirationRunner.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/PassivationExpirationRunner.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi.impl;
+
+import org.jboss.ejb3.cache.spi.PassivationExpirationProcessor;
+
+/**
+ * TimerTask that will periodically invoke
+ * {@link PassivationExpirationProcessor#processPassivationExpiration()}
+ * on a single processor.
+ *
+ * @author Brian Stansberry
+ */
+public class PassivationExpirationRunner
+ extends AbstractTimerTask
+{
+ private PassivationExpirationProcessor processor;
+
+ /**
+ * Create a new PassivationExpirationRunner.
+ *
+ */
+ public PassivationExpirationRunner(PassivationExpirationProcessor processor,
+ String timerName, long interval)
+ {
+ super(timerName, interval);
+
+ assert processor != null : "processor is null";
+ this.processor = processor;
+ }
+
+ public void run()
+ {
+ processor.processPassivationExpiration();
+ }
+
+}
Copied: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java (from rev 70283, projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/impl/SerializationGroupImpl.java)
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupImpl.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,384 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.cache.spi.impl;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.Identifiable;
+import org.jboss.ejb3.cache.SerializationGroup;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.logging.Logger;
+import org.jboss.util.id.GUID;
+
+/**
+ * Defines a group of serializable objects which must be serialized in
+ * one unit of work.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @author Brian Stansberry
+ * @version $Revision: $
+ */
+public class SerializationGroupImpl<T extends CacheItem>
+ extends AbstractBackingCacheEntry<T>
+ implements SerializationGroup<T>, BackingCacheEntry<T>
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -6181048392582344057L;
+
+ private static final Logger log = Logger.getLogger(SerializationGroupImpl.class);
+
+ private Object id = new GUID();
+
+ /**
+ * The actual underlying objects passed in via addMember(). We store them
+ * here so they aren't lost when they are cleared from the values
+ * stored in the "members" map.
+ */
+ private Map<Object, T> memberObjects = new ConcurrentHashMap<Object, T>();
+
+ /**
+ * The active group members. We don't serialize these. Rather, it is
+ * the responsibility of members to reassociate themselves with the
+ * group upon deserialization (via addActive())
+ */
+ private transient Map<Object, SerializationGroupMember<T>> active =
+ new HashMap<Object, SerializationGroupMember<T>>();
+
+ /**
+ * Set of keys passed to {@link #addInUse(Object)}
+ */
+ private transient Set<Object> inUseKeys = new HashSet<Object>();
+
+ /** Transient ref to our group cache; used to validate compatibility */
+ private transient PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache;
+
+ /** Is this object used in a clustered cache? */
+ private boolean clustered;
+
+ private transient boolean invalid;
+
+ public Object getId()
+ {
+ return id;
+ }
+
+ /**
+ * Gets whether this groups supports (and requires) clustering functionality
+ * from its members.
+ *
+ * @return <code>true</code> if clustering is supported, <code>false</code>
+ * otherwise
+ */
+ public boolean isClustered()
+ {
+ return clustered;
+ }
+
+ /**
+ * Sets whether this groups supports (and requires) clustering functionality
+ * from its members.
+ *
+ * @return
+ */
+ public void setClustered(boolean clustered)
+ {
+ this.clustered = clustered;
+ }
+
+ /**
+ * Initially associates a new member with the group. Also
+ * {@link #addActive(SerializationGroupMember) marks the member as
+ * active}.
+ *
+ * @param member
+ *
+ * @throws IllegalStateException if <code>member</code> was previously
+ * added to the group
+ * @throws IllegalArgumentException if the
+ * {@link SerializationGroupMember#isClustered() member's support for clustering}
+ * does not match {@link #isClustered() our own}.
+ */
+ public void addMember(SerializationGroupMember<T> member)
+ {
+ Object key = member.getId();
+ if (memberObjects.containsKey(key))
+ throw new IllegalStateException(member + " is already a member");
+ log.trace("add member " + key + ", " + member);
+ memberObjects.put(key, member.getUnderlyingItem());
+ active.put(key, member);
+ }
+
+ /**
+ * Remove the specified member from the group.
+ *
+ * @param key the {@link Identifiable#getId() id} of the member
+ */
+ public void removeMember(Object key)
+ {
+ removeActive(key);
+ memberObjects.remove(key);
+ }
+
+ /**
+ * Gets the number of group members.
+ */
+ public int size()
+ {
+ return memberObjects.size();
+ }
+
+ /**
+ * Returns the {@link SerializationGroupMember#getUnderlyingItem() member object}
+ * associated with the member whose {@link Identifiable#getId() id}
+ * matches <code>key</code>.
+ *
+ * @param key the {@link Identifiable#getId() id} of the member
+ *
+ * @return the object associated with the member, or <code>null</code> if
+ * <code>key</code> does not identify a member.
+ */
+ public T getMemberObject(Object key)
+ {
+ return memberObjects.get(key);
+ }
+
+ public Iterator<T> iterator()
+ {
+ return new UnmodifiableIterator<T>(memberObjects.values().iterator());
+ }
+
+ /**
+ * Prepare members for passivation.
+ */
+ public void prePassivate()
+ {
+ for(SerializationGroupMember<T> member : active.values())
+ {
+ member.prePassivate();
+ }
+ active.clear();
+ }
+
+ /**
+ * Notification that the group has been activated from a passivated state.
+ */
+ public void postActivate()
+ {
+ invalid = false;
+ }
+
+ /**
+ * Prepare members for replication.
+ */
+ public void preReplicate()
+ {
+ for(SerializationGroupMember<T> member : active.values())
+ {
+ member.preReplicate();
+ }
+ active.clear();
+ }
+
+ /**
+ * Notification that the previously replicated group has been retrieved from
+ * a clustered cache.
+ */
+ public void postReplicate()
+ {
+ invalid = false;
+ }
+
+ /**
+ * Records that the given member is "active"; i.e. needs to have
+ * @PrePassivate callbacks invoked before serialization.
+ *
+ * @param member the member
+ *
+ * @throws IllegalStateException if <code>member</code> wasn't previously
+ * added to the group via
+ * {@link #addMember(SerializationGroupMember)}
+ */
+ public void addActive(SerializationGroupMember<T> member)
+ {
+ Object key = member.getId();
+ if (!memberObjects.containsKey(key))
+ throw new IllegalStateException(member + " is not a member of " + this);
+ active.put(key, member);
+ }
+
+ /**
+ * Records that the given member is no longer "active"; i.e. does not need
+ * to have @PrePassivate callbacks invoked before serialization.
+ *
+ * @param key the {@link Identifiable#getId() id} of the member
+ *
+ * @throws IllegalStateException if <code>member</code> wasn't previously
+ * added to the group via
+ * {@link #addMember(SerializationGroupMember)}
+ */
+ public void removeActive(Object key)
+ {
+ active.remove(key);
+ }
+
+ /**
+ * Notification that the given member is "in use", and therefore the
+ * group should not be serialized.
+ *
+ * @param key the {@link Identifiable#getId() id} of the member
+ *
+ * @throws IllegalStateException if <code>member</code> wasn't previously
+ * added to the group via
+ * {@link #addMember(SerializationGroupMember)}
+ */
+ public void addInUse(Object key)
+ {
+ if (!memberObjects.containsKey(key))
+ throw new IllegalStateException(key + " is not a member of " + this);
+ inUseKeys.add(key);
+ setInUse(true);
+ }
+
+ /**
+ * Notification that the given member is no longer "in use", and therefore
+ * should not prevent the group being serialized.
+ *
+ * @param key the {@link Identifiable#getId() id} of the member
+ *
+ * @throws IllegalStateException if <code>member</code> wasn't previously
+ * added to the group via
+ * {@link #addMember(SerializationGroupMember)}
+ */
+ public void removeInUse(Object key)
+ {
+ if (inUseKeys.remove(key))
+ {
+ setLastUsed(System.currentTimeMillis());
+ }
+ else if (!memberObjects.containsKey(key))
+ {
+ throw new IllegalStateException(key + " is not a member of " + this);
+ }
+ }
+
+ /**
+ * Gets the number of members currently in use.
+ */
+ public int getInUseCount()
+ {
+ return inUseKeys.size();
+ }
+
+ /**
+ * Always returns <code>true</code>.
+ */
+ public boolean isModified()
+ {
+ return true;
+ }
+
+ /**
+ * Returns true if this object has been passivated (meaning whoever
+ * holds a ref to it is holding an out-of-date object)
+ *
+ * @return
+ */
+ public boolean isInvalid()
+ {
+ return invalid;
+ }
+
+ public void setInvalid(boolean invalid)
+ {
+ this.invalid = invalid;
+ }
+
+ /**
+ * FIXME -- returns null; what should it do?
+ */
+ public T getUnderlyingItem()
+ {
+ return null;
+ }
+
+ public PassivatingBackingCache<T, SerializationGroupImpl<T>> getGroupCache()
+ {
+ return groupCache;
+ }
+
+ @Override
+ public String toString()
+ {
+ return super.toString() + "{id=" + id + "}";
+ }
+
+ public void setGroupCache(PassivatingBackingCache<T, SerializationGroupImpl<T>> groupCache)
+ {
+ this.groupCache = groupCache;
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ in.defaultReadObject();
+ active = new HashMap<Object, SerializationGroupMember<T>>();
+ inUseKeys = new HashSet<Object>();
+ }
+
+ private class UnmodifiableIterator<C extends CacheItem & Serializable> implements Iterator<C>
+ {
+ private Iterator<C> backingIterator;
+
+ public UnmodifiableIterator(Iterator<C> backingIterator)
+ {
+ assert backingIterator != null : "backingIterator is null";
+
+ this.backingIterator = backingIterator;
+ }
+
+ public boolean hasNext()
+ {
+ return backingIterator.hasNext();
+ }
+
+ public C next()
+ {
+ return backingIterator.next();
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException("remove is not supported");
+ }
+ }
+
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/main/java/org/jboss/ejb3/cache/spi/impl/SerializationGroupMember.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,282 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.cache.spi.impl;
+
+import java.io.IOException;
+
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+
+/**
+ * A member of a {@link SerializationGroupImpl}.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class SerializationGroupMember<T extends CacheItem>
+ extends AbstractBackingCacheEntry<T>
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 7268142730501106252L;
+
+ /**
+ * Identifier for our underlying object
+ */
+ private Object id;
+
+ /**
+ * The underlying object (e.g. bean context).
+ * Preferably, this field would be transient. It isn't now because it is
+ * possible this entry will never be assigned to a PassivationGroup,
+ * in which case we need to serialize obj.
+ */
+ private T obj;
+
+ /**
+ * Hack. We hold two refs to our object; one we clear in prePassivate,
+ * one we keep, but it's transient. getUnderlyingItem() returns
+ * whichever is available, making it available for passivation callbacks.
+ */
+ private transient T transientObj;
+
+ /** The group. Never serialize the group; only the groupCache does that */
+ private transient SerializationGroupImpl<T> group;
+
+ /**
+ * Id for our group; serialize this so we can find our group again
+ * after deserialization on a remote node.
+ */
+ private Object groupId;
+
+ private boolean clustered;
+
+ private boolean preReplicated;
+ private boolean prePassivated;
+
+ /** The cache that's handling us */
+ private transient PassivatingBackingCache<T, SerializationGroupMember<T>> cache;
+
+ public SerializationGroupMember(T obj, PassivatingBackingCache<T, SerializationGroupMember<T>> cache)
+ {
+ assert obj != null : "obj is null";
+ assert cache != null : "cache is null";
+
+ this.obj = transientObj = obj;
+ this.id = obj.getId();
+ this.cache = cache;
+ this.clustered = cache.isClustered();
+ }
+
+ public Object getId()
+ {
+ return id;
+ }
+
+ public boolean isModified()
+ {
+ return (obj != null && obj.isModified());
+ }
+
+ /**
+ * Gets whether this member supports clustering functionality.
+ *
+ * @return <code>true</code> if clustering is supported, <code>false</code>
+ * otherwise
+ */
+ public boolean isClustered()
+ {
+ return clustered;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getUnderlyingItem()
+ {
+ return obj == null ? transientObj : obj;
+ }
+
+ /**
+ * Sets the underlying {@link CacheItem} associated with this group member.
+ *
+ * @param item the cache item
+ */
+ public void setUnderlyingItem(T obj)
+ {
+ this.obj = transientObj = obj;
+ }
+
+ /**
+ * Gets the {@link SerializationGroupImpl} of which this object is a member.
+ *
+ * @return the group. May return <code>null</code>
+ */
+ public SerializationGroupImpl<T> getGroup()
+ {
+ return (group == null || group.isInvalid()) ? null : group;
+ }
+
+ /**
+ * Sets the {@link SerializationGroupImpl} of which this object is a member.
+ *
+ * @param the group. May be <code>null</code>
+ */
+ public void setGroup(SerializationGroupImpl<T> group)
+ {
+ this.group = group;
+ if (group != null)
+ this.groupId = group.getId();
+ }
+
+ /**
+ * Gets the id for the group
+ *
+ * @return
+ */
+ public Object getGroupId()
+ {
+ return groupId;
+ }
+
+ /**
+ * Prepare the group member for passivation. Ensure any @PrePassivate
+ * callback is invoked on the underlying object. If we are a member of a
+ * group, ensure any reference to the
+ * {@link #getUnderlyingItem() underlying object} or to the
+ * {@link #getGroup()} is nulled.
+ */
+ public void prePassivate()
+ {
+ // make sure we don't passivate the group twice
+ group = null;
+
+ // null out obj so when delegate passivates this entry
+ // we don't serialize it. It serializes with the PassivationGroup only
+ // We still have a ref to transientObj, so it can be retrieved
+ // for passivation callbacks
+ obj = null;
+
+ cache.passivate(this.id);
+ }
+
+ public boolean isPrePassivated()
+ {
+ return prePassivated;
+ }
+
+ public void setPrePassivated(boolean prePassivated)
+ {
+ this.prePassivated = prePassivated;
+ }
+
+ /**
+ * Notification that the group has been activated from a passivated state.
+ */
+ public void postActivate()
+ {
+ // no-op
+ }
+
+ /**
+ * Prepare the group member for replication. Ensure any required callback
+ * (e.g. @PreReplicaate) is invoked on the underlying object. If we are a
+ * member of a group, ensure any reference to the
+ * {@link #getUnderlyingItem() underlying object} or to the
+ * {@link #getGroup()} is nulled.
+ *
+ * @throws UnsupportedOperationException if {@link #isClustered()} returns
+ * <code>false</code>
+ */
+ public void preReplicate()
+ {
+ // make sure we don't replicate the group twice
+ group = null;
+ // null out obj so when delegate serializes this entry
+ // we don't serialize it. It serializes with the PassivationGroup only
+ obj = null;
+
+ // FIXME -- what does this do for us?
+ // Nothing -- it will fail
+// cache.release(this);
+ }
+
+ public boolean isPreReplicated()
+ {
+ return preReplicated;
+ }
+
+ public void setPreReplicated(boolean preReplicated)
+ {
+ this.preReplicated = preReplicated;
+ }
+
+ /**
+ * Notification that the previously replicated group has been retrieved from
+ * a clustered cache.
+ */
+ public void postReplicate()
+ {
+ // no-op
+ }
+
+ public void setInUse(boolean inUse)
+ {
+ super.setInUse(inUse);
+
+ // Tell our group about it
+ if (group != null)
+ {
+ if (inUse)
+ group.addActive(this);
+ else
+ group.removeActive(id);
+ }
+ }
+
+ /**
+ * Allows our controlling {@link PassivatingBackingCache} to provide
+ * us a reference after deserialization.
+ *
+ * @param delegate
+ */
+ public void setPassivatingCache(PassivatingBackingCache<T, SerializationGroupMember<T>> delegate)
+ {
+ assert delegate != null : "delegate is null";
+
+ this.cache = delegate;
+ }
+
+ @Override
+ public String toString()
+ {
+ return super.toString() + "{id=" + id + ",obj=" + obj + ",groupId=" + groupId + ",group=" + group + "}";
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException
+ {
+ if (groupId != null)
+ {
+ group = null;
+ obj = null;
+ }
+ out.defaultWriteObject();
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/impl/backing/PassivatingBackingCacheImplUnitTestCase.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.cache.impl.backing;
+
+import junit.framework.TestCase;
+
+import org.jboss.ejb3.cache.impl.TransactionalCache;
+import org.jboss.ejb3.cache.impl.backing.PassivatingBackingCacheImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+import org.jboss.ejb3.test.cache.mock.CacheType;
+import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
+import org.jboss.ejb3.test.cache.mock.MockBeanContext;
+import org.jboss.ejb3.test.cache.mock.MockCacheConfig;
+import org.jboss.ejb3.test.cache.mock.MockEjb3System;
+import org.jboss.ejb3.test.cache.mock.MockXPC;
+
+/**
+ * Comment
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: 65339 $
+ */
+public class PassivatingBackingCacheImplUnitTestCase extends TestCase
+{
+
+ /**
+ * Peek of an active object should not change it state.
+ */
+ @SuppressWarnings("unchecked")
+ public void testPeekActive() throws Exception
+ {
+ MockEjb3System system = new MockEjb3System(false, CacheType.SIMPLE);
+ MockXPC sharedXPC = new MockXPC();
+ MockCacheConfig config = new MockCacheConfig();
+ config.setIdleTimeoutSeconds(4);
+ MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
+ TransactionalCache cache = (TransactionalCache) container.getCache();
+ PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMember<MockBeanContext>> backingCache = (PassivatingBackingCacheImpl<MockBeanContext, SerializationGroupMember<MockBeanContext>>) cache.getBackingCache();
+ SerializationGroupMember<MockBeanContext> obj = backingCache.create(null, null);
+ Object key = obj.getId();
+
+ backingCache.peek(key);
+
+ try
+ {
+ backingCache.release(key);
+ fail("Should not be able to release entry that has not been gotten");
+ }
+ catch (IllegalStateException good)
+ {
+ backingCache.get(key);
+ backingCache.release(key);
+ }
+ finally
+ {
+ backingCache.remove(key);
+ }
+
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/Ejb3CacheTestCaseBase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/Ejb3CacheTestCaseBase.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/Ejb3CacheTestCaseBase.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.integrated;
+
+import org.jboss.ejb3.test.cache.mock.MockRegistry;
+import org.jboss.ejb3.test.cache.mock.tm.MockTransactionManager;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class Ejb3CacheTestCaseBase extends TestCase
+{
+
+ /**
+ * Create a new Ejb3CacheTestCaseBase.
+ *
+ */
+ public Ejb3CacheTestCaseBase()
+ {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Create a new Ejb3CacheTestCaseBase.
+ *
+ * @param name
+ */
+ public Ejb3CacheTestCaseBase(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ cleanSystem();
+ super.tearDown();
+ }
+
+ protected void cleanSystem()
+ {
+ MockRegistry.clear();
+ MockTransactionManager.cleanupTransactions();
+ MockTransactionManager.cleanupTransactionManagers();
+ }
+
+ protected static void wait(Object obj) throws InterruptedException
+ {
+ synchronized (obj)
+ {
+ obj.wait(5000);
+ }
+ }
+
+ protected static void sleep(long micros)
+ {
+ try
+ {
+ Thread.sleep(micros);
+ }
+ catch (InterruptedException e)
+ {
+ // ignore
+ }
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/GroupAwareTransactionalCacheUnitTestCase.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.cache.integrated;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.test.cache.mock.CacheType;
+import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
+import org.jboss.ejb3.test.cache.mock.MockBeanContext;
+import org.jboss.ejb3.test.cache.mock.MockCacheConfig;
+import org.jboss.ejb3.test.cache.mock.MockEjb3System;
+import org.jboss.ejb3.test.cache.mock.MockPassivationManager;
+import org.jboss.ejb3.test.cache.mock.MockXPC;
+import org.jboss.logging.Logger;
+
+/**
+ * Comment
+ *
+ * @author Brian Stansberry
+ * @version $Revision: 65920 $
+ */
+public class GroupAwareTransactionalCacheUnitTestCase extends TransactionalCacheUnitTestCase
+{
+ private static final Logger log = Logger.getLogger(GroupAwareTransactionalCacheUnitTestCase.class);
+
+ @Override
+ protected Cache<MockBeanContext> createCache() throws Exception
+ {
+ MockEjb3System system = new MockEjb3System(false, CacheType.SIMPLE);
+ MockBeanContainer ejb = system.deployBeanContainer("test", null, CacheType.SIMPLE);
+ return ejb.getCache();
+ }
+
+ public void testNonGroupedPassivation() throws Exception
+ {
+ MockEjb3System system = new MockEjb3System(false, CacheType.SIMPLE);
+ MockXPC sharedXPC = new MockXPC();
+ MockCacheConfig config = new MockCacheConfig();
+ config.setIdleTimeoutSeconds(4);
+ MockBeanContainer container = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
+ Cache<MockBeanContext> cache = container.getCache();
+
+ Object key = cache.create(null, null).getId();
+ MockBeanContext obj = cache.get(key);
+
+ cache.finished(obj);
+ obj = null;
+
+ wait(container);
+
+ MockPassivationManager pass = (MockPassivationManager) container.getPassivationManager();
+
+ assertEquals("MockBeanContext should have been passivated", 1, pass.getPrePassivateCount());
+
+ obj = cache.get(key);
+ assertNotNull(obj);
+
+ assertEquals("MockBeanContext should have been activated", 1, pass.getPostActivateCount());
+
+ sleep(3000);
+
+ assertEquals("MockBeanContext should not have been passivated", 1, pass.getPrePassivateCount());
+
+ cache.finished(obj);
+ obj = null;
+
+ wait(container);
+
+ assertEquals("MockBeanContext should have been passivated", 2, pass.getPrePassivateCount());
+ }
+
+
+
+ public void testSimpleGroupPassivation() throws Exception
+ {
+ MockEjb3System system = new MockEjb3System(false, CacheType.SIMPLE);
+ MockXPC sharedXPC = new MockXPC();
+ MockCacheConfig config = new MockCacheConfig();
+ config.setIdleTimeoutSeconds(1);
+ MockBeanContainer container1 = system.deployBeanContainer("MockBeanContainer1", null, CacheType.SIMPLE, config, sharedXPC);
+ MockBeanContainer container2 = system.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.SIMPLE, config, sharedXPC);
+
+ log.info("Containers deployed");
+
+ assertTrue(container1.hasChild(container2));
+
+ try
+ {
+ Object key1 = container1.getCache().create(null, null).getId();
+ MockBeanContext firstCtx1;
+ MockBeanContext ctx1 = firstCtx1 = container1.getCache().get(key1);
+
+ assertEquals(sharedXPC, ctx1.getXPC());
+ Object key2 = ctx1.getChild(container2.getName());
+ MockBeanContext ctx2 = container2.getCache().get(key2);
+ assertNotNull(ctx2);
+ assertEquals(sharedXPC, ctx2.getXPC());
+
+ container2.getCache().finished(ctx2);
+ container1.getCache().finished(ctx1);
+
+ log.info("Finished with contexts");
+
+ sleep(2100);
+
+ MockPassivationManager pass1 = (MockPassivationManager) container1.getPassivationManager();
+ MockPassivationManager pass2 = (MockPassivationManager) container2.getPassivationManager();
+
+
+ assertEquals("ctx1 should have been passivated", 1, pass1.getPrePassivateCount());
+ assertEquals("ctx2 should have been passivated", 1, pass2.getPrePassivateCount());
+
+ log.info("Restoring ctx2");
+
+ ctx2 = container2.getCache().get(key2);
+
+ log.info("ctx2 = " + ctx2);
+ assertNotNull(ctx2);
+
+ log.info("Restoring ctx1");
+
+ ctx1 = container1.getCache().get(key1);
+
+ log.info("ctx1 = " + ctx1);
+
+ assertTrue("ctx1 must be different than firstCtx1 (else no passivation has taken place)", ctx1 != firstCtx1);
+
+ assertNotNull(ctx1.getXPC());
+ assertEquals(ctx1.getXPC(), ctx2.getXPC());
+
+ container1.getCache().finished(ctx1);
+ container2.getCache().finished(ctx2);
+
+ }
+ finally
+ {
+ container1.stop();
+ container2.stop();
+ }
+ }
+
+ /**
+ * Test call to bean1 that calls into bean2 that calls back into bean1
+ */
+ public void testRecursiveCalls()
+ {
+ // FIXME implement testRecursiveCalls() -- which will fail :(
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/TransactionalCacheUnitTestCase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/TransactionalCacheUnitTestCase.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/integrated/TransactionalCacheUnitTestCase.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.cache.integrated;
+
+import javax.ejb.NoSuchEJBException;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.test.cache.mock.CacheType;
+import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
+import org.jboss.ejb3.test.cache.mock.MockBeanContext;
+import org.jboss.ejb3.test.cache.mock.MockEjb3System;
+
+/**
+ * Comment
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @author Brian Stansberry
+ * @version $Revision: $
+ */
+public class TransactionalCacheUnitTestCase extends Ejb3CacheTestCaseBase
+{
+ protected Cache<MockBeanContext> createCache() throws Exception
+ {
+ MockEjb3System system = new MockEjb3System(false, CacheType.NON_PASSIVATING);
+ MockBeanContainer ejb = system.deployBeanContainer("test", null, CacheType.NON_PASSIVATING);
+ return ejb.getCache();
+ }
+
+ public void testNonExistingGet() throws Exception
+ {
+ Cache<MockBeanContext> cache = createCache();
+
+ try
+ {
+ cache.get(1);
+ fail("Object 1 should not be in cache");
+ }
+ catch(NoSuchEJBException e)
+ {
+ // good
+ }
+ }
+
+ public void testSimpleLifeCycle() throws Exception
+ {
+ Cache<MockBeanContext> cache = createCache();
+
+ Object key = cache.create(null, null).getId();
+ MockBeanContext object = cache.get(key);
+
+ assertNotNull(object);
+
+ cache.remove(key);
+
+ try
+ {
+ cache.get(key);
+ fail("Object should not be in cache");
+ }
+ catch(NoSuchEJBException e)
+ {
+ // good
+ }
+ }
+
+ public void testSequentialGetCalls() throws Exception
+ {
+ Cache<MockBeanContext> cache = createCache();
+
+ Object key = cache.create(null, null).getId();
+ MockBeanContext object = cache.get(key);
+
+ assertNotNull(object);
+
+ try
+ {
+ cache.get(key);
+ fail("Two sequential get calls should throw ISE");
+ }
+ catch(IllegalStateException e)
+ {
+ // good
+ }
+ finally {
+ cache.remove(key);
+ }
+ }
+
+ public void testSequentialFinishedCalls() throws Exception
+ {
+ Cache<MockBeanContext> cache = createCache();
+
+ Object key = cache.create(null, null).getId();
+ MockBeanContext object = cache.get(key);
+
+ assertNotNull(object);
+
+ cache.finished(object);
+
+ try
+ {
+ cache.finished(object);
+ fail("Two sequential finished calls should throw ISE");
+ }
+ catch(IllegalStateException e)
+ {
+ // good
+ }
+ finally {
+ cache.remove(key);
+ }
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/CacheType.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/CacheType.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/CacheType.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+/**
+ * Enumeration of the types of caches we'll test
+ *
+ * @author Brian Stansberry
+ */
+public enum CacheType {
+
+ NON_PASSIVATING("NonPassivatingCache"),
+ SIMPLE("SimpleStatefulCache"),
+ DISTRIBUTED("StatefulTreeCache");
+
+ private String mapKey;
+
+ private CacheType(String mapKey)
+ {
+ this.mapKey = mapKey;
+ }
+
+ public String mapKey()
+ {
+ return mapKey;
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContainer.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,127 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.PassivationManager;
+import org.jboss.ejb3.cache.StatefulCacheFactory;
+import org.jboss.ejb3.cache.StatefulCacheFactoryRegistry;
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockBeanContainer
+{
+ private final String containerName;
+ private final String cacheFactoryName;
+ private final StatefulCacheFactoryRegistry<MockBeanContext> cacheFactoryRegistry;
+ private final MockCacheConfig cacheConfig;
+ private final MockStatefulObjectFactory objectFactory;
+ private final MockPassivationManager passivationManager;
+
+ private Cache<MockBeanContext> cache;
+ private Set<MockBeanContainer> children;
+
+ private MockXPC xpc;
+
+ public MockBeanContainer(String containerName, String cacheFactoryName,
+ StatefulCacheFactoryRegistry<MockBeanContext> cacheFactoryRegistry,
+ MockCacheConfig cacheConfig)
+ {
+ this.containerName = containerName;
+ this.cacheFactoryName = cacheFactoryName;
+ this.cacheFactoryRegistry = cacheFactoryRegistry;
+ this.cacheConfig = cacheConfig;
+
+ this.objectFactory = new MockStatefulObjectFactory(this);
+ this.passivationManager = new MockPassivationManager();
+ this.children = new HashSet<MockBeanContainer>();
+
+ MockRegistry.put(this.containerName, this);
+ }
+
+ public void start() throws Exception
+ {
+ StatefulCacheFactory<MockBeanContext> cacheFactory = cacheFactoryRegistry.getCacheFactory(cacheFactoryName);
+ cache = cacheFactory.createCache(containerName, objectFactory, passivationManager, cacheConfig);
+ cache.start();
+ }
+
+ public void stop()
+ {
+ cache.stop();
+ MockRegistry.remove(containerName);
+ }
+
+ public String getName()
+ {
+ return containerName;
+ }
+
+ public Cache<MockBeanContext> getCache()
+ {
+ return cache;
+ }
+
+ public Set<MockBeanContainer> getChildren()
+ {
+ return children;
+ }
+
+ public void addChild(MockBeanContainer child)
+ {
+ children.add(child);
+ }
+
+ public boolean hasChild(MockBeanContainer child)
+ {
+ return children.contains(child);
+ }
+
+ public MockXPC getXPC()
+ {
+ return xpc;
+ }
+
+ public void setXPC(MockXPC xpc)
+ {
+ this.xpc = xpc;
+ }
+
+ public StatefulObjectFactory<MockBeanContext> getStatefulObjectFactory()
+ {
+ return objectFactory;
+ }
+
+ public PassivationManager<MockBeanContext> getPassivationManager()
+ {
+ return passivationManager;
+ }
+
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockBeanContext.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,208 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jboss.ejb3.cache.Cache;
+import org.jboss.ejb3.cache.SerializationGroup;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockBeanContext extends MockCacheItem
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 3209950231614290498L;
+
+ private final String containerName;
+
+ private MockXPC xpc;
+ private MockEntity entity;
+
+ private int preReplicateCount;
+ private int prePassivateCount;
+ private int postReplicateCount;
+ private int postActivateCount;
+ private Map<String, Object> children;
+
+ public MockBeanContext(String containerName)
+ {
+ super(createId());
+ this.containerName = containerName;
+ this.children = new HashMap<String, Object>();
+ }
+
+ public MockBeanContainer getContainer()
+ {
+ return (MockBeanContainer) MockRegistry.get(containerName);
+ }
+
+ public void addChild(MockBeanContext child)
+ {
+ // Just store the id; tests get the id from getChild() and
+ // then call get(id) on the child container's cache.
+ // This simulates how an internal call via a nested bean's
+ // proxy would work
+ children.put(child.containerName, child.getId());
+ }
+
+ public Object getChild(String containerName)
+ {
+ return children.get(containerName);
+ }
+
+ public void remove()
+ {
+ if (xpc != null)
+ {
+ boolean closeIt = true;
+ Cache<MockBeanContext> cache = getContainer().getCache();
+ if (cache.isGroupAware())
+ {
+ SerializationGroup<MockBeanContext> group = cache.getGroup(this);
+ if (group != null)
+ {
+ for(Iterator<MockBeanContext> it = group.iterator(); it.hasNext();)
+ {
+ MockBeanContext ctx = it.next();
+ if (ctx != this)
+ {
+ if (xpc.equals(ctx.getXPC()))
+ {
+ closeIt = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (closeIt)
+ xpc.close();
+ }
+ }
+ }
+
+ public int getPreReplicateCount()
+ {
+ return preReplicateCount;
+ }
+ public int getPrePassivateCount()
+ {
+ return prePassivateCount;
+ }
+ public int getPostReplicateCount()
+ {
+ return postReplicateCount;
+ }
+ public int getPostActivateCount()
+ {
+ return postActivateCount;
+ }
+
+ public MockXPC getXPC()
+ {
+ return xpc;
+ }
+
+ public void setXPC(MockXPC sharedObject)
+ {
+ this.xpc = sharedObject;
+ }
+
+ public void preReplicate()
+ {
+ preReplicateCount++;
+ synchronized(this)
+ {
+ notifyAll();
+ }
+ }
+
+ public void postReplicate()
+ {
+ postReplicateCount++;
+ synchronized(this)
+ {
+ notifyAll();
+ }
+ }
+
+ public void prePassivate()
+ {
+ prePassivateCount++;
+ synchronized(this)
+ {
+ notifyAll();
+ }
+ }
+
+ public void postActivate()
+ {
+ postActivateCount++;
+ synchronized(this)
+ {
+ notifyAll();
+ }
+ }
+
+ // -- Underlying bean operations
+
+ public void createEntity()
+ {
+ entity = xpc.createEntity();
+ setModified(true);
+ }
+
+ public MockEntity getEntity()
+ {
+ MockEntity was = entity;
+ entity = xpc.getEntity();
+ if (was != entity)
+ setModified(true);
+ return entity;
+ }
+
+ public void removeEntity()
+ {
+ xpc.removeEntity();
+ if (entity != null)
+ {
+ entity = null;
+ setModified(true);
+ }
+ }
+
+ public void invokeNonModifying()
+ {
+ // no-op
+ }
+
+ public void invokeModifying()
+ {
+ setModified(true);
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheConfig.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheConfig.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheConfig.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,110 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.cache.mock;
+
+import java.lang.annotation.Annotation;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+
+/**
+ * Implementation of CacheConfig Annotation
+ *
+ * @author Brian Stansberry
+ * @version $Revision: $
+ */
+public class MockCacheConfig implements CacheConfig
+{
+ // Instance Members
+
+ private String name = "";
+
+ private int maxSize = CacheConfig.DEFAULT_NONCLUSTERED_MAX_SIZE;
+
+ private long idleTimeoutSeconds = CacheConfig.DEFAULT_IDLE_TIMEOUT_SECONDS;
+
+ private long removalTimeoutSeconds = CacheConfig.DEFAULT_REMOVAL_TIMEOUT_SECONDS;
+
+ private boolean replicationIsPassivation = CacheConfig.DEFAULT_REPL_IS_PASV;
+
+ // Constructor
+
+ public MockCacheConfig()
+ {
+ }
+
+ // Accessors / Mutators
+
+ public String name()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public int maxSize()
+ {
+ return maxSize;
+ }
+
+ public void setMaxSize(int maxSize)
+ {
+ this.maxSize = maxSize;
+ }
+
+ public long idleTimeoutSeconds()
+ {
+ return idleTimeoutSeconds;
+ }
+
+ public void setIdleTimeoutSeconds(long idleTimeoutSeconds)
+ {
+ this.idleTimeoutSeconds = idleTimeoutSeconds;
+ }
+
+ public long removalTimeoutSeconds()
+ {
+ return removalTimeoutSeconds;
+ }
+
+ public void setRemovalTimeoutSeconds(long removalTimeoutSeconds)
+ {
+ this.removalTimeoutSeconds = removalTimeoutSeconds;
+ }
+
+ public boolean replicationIsPassivation()
+ {
+ return replicationIsPassivation;
+ }
+
+ public void setReplicationIsPassivation(boolean replicationIsPassivation)
+ {
+ this.replicationIsPassivation = replicationIsPassivation;
+ }
+
+ public Class<? extends Annotation> annotationType()
+ {
+ return CacheConfig.class;
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheItem.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheItem.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockCacheItem.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import org.jboss.ejb3.cache.CacheItem;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockCacheItem
+ extends MockIdentifiable
+ implements CacheItem
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 7660507283782503571L;
+
+ private boolean modified;
+
+ public MockCacheItem(long id)
+ {
+ super(id);
+ }
+
+ public boolean isModified()
+ {
+ boolean result = modified;
+ modified = false;
+ return result;
+ }
+
+ public void setModified(boolean modified)
+ {
+ this.modified = modified;
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEjb3System.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.cache.StatefulCacheFactory;
+import org.jboss.ejb3.cache.StatefulCacheFactoryRegistry;
+import org.jboss.ejb3.cache.impl.factory.GroupAwareCacheFactory;
+import org.jboss.ejb3.cache.impl.factory.NonClusteredIntegratedObjectStoreSource;
+import org.jboss.ejb3.cache.impl.factory.NonPassivatingCacheFactory;
+import org.jboss.ejb3.cache.impl.factory.PassivationExpirationCoordinatorImpl;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
+import org.jboss.ejb3.cache.spi.PassivationExpirationCoordinator;
+import org.jboss.ejb3.cache.spi.impl.AbstractStatefulCacheFactory;
+import org.jboss.ejb3.test.cache.mock.tm.MockTransactionManager;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockEjb3System
+{
+ private StatefulCacheFactoryRegistry<MockBeanContext> cacheFactoryRegistry;
+ private TransactionManager tm;
+ private PassivationExpirationCoordinator coordinator;
+
+ public MockEjb3System(boolean useCoordinator, CacheType cacheType)
+ {
+ this(MockTransactionManager.getInstance(), useCoordinator, cacheType);
+ }
+
+ public MockEjb3System(TransactionManager tm,
+ boolean useCoordinator,
+ CacheType cacheType)
+ {
+ this(tm, useCoordinator, new CacheType[] { cacheType });
+ }
+
+ public MockEjb3System(TransactionManager tm,
+ boolean useCoordinator,
+ CacheType[] availableTypes)
+ {
+ this.tm = tm;
+ if (useCoordinator)
+ coordinator = new PassivationExpirationCoordinatorImpl();
+
+ cacheFactoryRegistry = new StatefulCacheFactoryRegistry<MockBeanContext>();
+ if (availableTypes != null)
+ {
+ Map<String, StatefulCacheFactory<MockBeanContext>> factories =
+ new HashMap<String, StatefulCacheFactory<MockBeanContext>>();
+ for (CacheType type : availableTypes)
+ {
+ factories.put(type.mapKey(), buildCacheFactory(type));
+ }
+ cacheFactoryRegistry.setFactories(factories);
+ }
+ }
+
+ public StatefulCacheFactoryRegistry<MockBeanContext> getCacheFactoryRegistry()
+ {
+ return cacheFactoryRegistry;
+ }
+
+ public TransactionManager getTransactionManager()
+ {
+ return tm;
+ }
+
+ public PassivationExpirationCoordinator getCoordinator()
+ {
+ return coordinator;
+ }
+
+ public MockBeanContainer getMockBeanContainer(String containerName)
+ {
+ MockBeanContainer container = (MockBeanContainer) MockRegistry.get(containerName);
+ if (container == null)
+ throw new IllegalArgumentException("Container " + containerName + " not found");
+ return container;
+ }
+
+ public MockBeanContainer deployBeanContainer(String containerName,
+ String parentContainerName,
+ CacheType cacheType) throws Exception
+ {
+ return deployBeanContainer(containerName, parentContainerName, cacheType, new MockCacheConfig(), null, true);
+ }
+
+ public MockBeanContainer deployBeanContainer(String containerName,
+ String parentContainerName,
+ CacheType cacheType,
+ MockCacheConfig cacheConfig,
+ MockXPC xpc) throws Exception
+ {
+ return deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc, true);
+ }
+
+ public MockBeanContainer deployBeanContainer(String containerName,
+ String parentContainerName,
+ CacheType cacheType,
+ MockCacheConfig cacheConfig,
+ MockXPC xpc,
+ boolean start) throws Exception
+ {
+ MockBeanContainer parent = (parentContainerName == null) ? null : getMockBeanContainer(parentContainerName);
+ MockBeanContainer container = new MockBeanContainer(containerName, cacheType.mapKey(), cacheFactoryRegistry, cacheConfig);
+ container.setXPC(xpc);
+ if (parent != null)
+ parent.addChild(container);
+ if (start)
+ container.start();
+ return container;
+ }
+
+ protected StatefulCacheFactory<MockBeanContext> buildCacheFactory(CacheType type)
+ {
+ AbstractStatefulCacheFactory<MockBeanContext> factory = null;
+ switch(type) {
+ case NON_PASSIVATING:
+ factory = buildNonPassivatingCacheFactory();
+ break;
+ case SIMPLE:
+ factory = buildSimpleCacheFactory();
+ break;
+ case DISTRIBUTED:
+ factory = buildDistributedCacheFactory();
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown type " + type);
+ }
+
+ factory.setTransactionManager(tm);
+ factory.setPassivationExpirationCoordinator(coordinator);
+ // Process passivation/expiration as quickly as possible so tests run fast
+ factory.setDefaultPassivationExpirationInterval(1);
+
+ return factory;
+ }
+
+ private AbstractStatefulCacheFactory<MockBeanContext> buildNonPassivatingCacheFactory()
+ {
+ return new NonPassivatingCacheFactory<MockBeanContext>();
+ }
+
+ private AbstractStatefulCacheFactory<MockBeanContext> buildSimpleCacheFactory()
+ {
+ NonClusteredIntegratedObjectStoreSource<MockBeanContext> source =
+ new NonClusteredIntegratedObjectStoreSource<MockBeanContext>();
+ return new GroupAwareCacheFactory<MockBeanContext>(source);
+ }
+
+ private AbstractStatefulCacheFactory<MockBeanContext> buildDistributedCacheFactory()
+ {
+ return new GroupAwareCacheFactory<MockBeanContext>(getDistributedStoreSource());
+ }
+
+ protected IntegratedObjectStoreSource<MockBeanContext> getDistributedStoreSource()
+ {
+ throw new UnsupportedOperationException("Distributed caching not supported");
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEntity.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEntity.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockEntity.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import java.io.Serializable;
+
+/**
+ * A SharedObject.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class MockEntity implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockIdentifiable.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockIdentifiable.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockIdentifiable.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.cache.mock;
+
+import java.io.Serializable;
+
+import org.jboss.ejb3.cache.Identifiable;
+
+/**
+ * Comment
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision: $
+ */
+public class MockIdentifiable implements Identifiable, Serializable
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 828205583403324513L;
+
+ private static volatile long currentId = 0;
+
+ public static long createId()
+ {
+ return ++currentId;
+ }
+
+ private long id;
+
+ public MockIdentifiable(long id)
+ {
+ this.id = id;
+ }
+
+ public Object getId()
+ {
+ return id;
+ }
+
+ @Override
+ public String toString()
+ {
+ return super.toString() + "{id=" + id + "}";
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockPassivationManager.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockPassivationManager.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockPassivationManager.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import org.jboss.ejb3.cache.PassivationManager;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockPassivationManager
+ implements PassivationManager<MockBeanContext>
+{
+ private int preReplicateCount;
+ private int prePassivateCount;
+ private int postReplicateCount;
+ private int postActivateCount;
+
+ public void postActivate(MockBeanContext ctx)
+ {
+ ctx.postActivate();
+ postActivateCount++;
+ }
+
+ public void postReplicate(MockBeanContext ctx)
+ {
+ ctx.postReplicate();
+ postReplicateCount++;
+ }
+
+ public void prePassivate(MockBeanContext ctx)
+ {
+ ctx.prePassivate();
+ prePassivateCount++;
+ }
+
+ public void preReplicate(MockBeanContext ctx)
+ {
+ ctx.preReplicate();
+ preReplicateCount++;
+ }
+
+ public int getPreReplicateCount()
+ {
+ return preReplicateCount;
+ }
+
+ public int getPrePassivateCount()
+ {
+ return prePassivateCount;
+ }
+
+ public int getPostReplicateCount()
+ {
+ return postReplicateCount;
+ }
+
+ public int getPostActivateCount()
+ {
+ return postActivateCount;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockRegistry.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockRegistry.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockRegistry.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,91 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author Brian Stansberry
+ */
+public class MockRegistry
+{
+ private static final Map<Object, Object> registry = new ConcurrentHashMap<Object, Object>();
+
+ public static Object put(Object key, Object value)
+ {
+ return registry.put(new RegistryKey(key), value);
+ }
+
+ public static Object get(Object key)
+ {
+ return registry.get(new RegistryKey(key));
+ }
+
+ public static Object remove(Object key)
+ {
+ return registry.remove(new RegistryKey(key));
+ }
+
+ public static void clear()
+ {
+ registry.clear();
+ }
+
+ private static class RegistryKey
+ {
+ private ClassLoader cl;
+ private Object key;
+
+ RegistryKey(Object key)
+ {
+ this.key = key;
+ this.cl = Thread.currentThread().getContextClassLoader();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+
+ if (obj instanceof RegistryKey)
+ {
+ RegistryKey other = (RegistryKey) obj;
+ return (cl.equals(other.cl) && key.equals(other.key));
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = 19;
+ result = 51 * result + cl.hashCode();
+ result = 51 * result + key.hashCode();
+ return result;
+ }
+
+
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockStatefulObjectFactory.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import org.jboss.ejb3.cache.StatefulObjectFactory;
+
+
+/**
+ * @author Brian Stansberry
+ */
+public class MockStatefulObjectFactory
+ implements StatefulObjectFactory<MockBeanContext>
+{
+ private final MockBeanContainer container;
+
+ private int creationCount;
+ private int groupCreationCount;
+ private int destroyCount;
+
+ public MockStatefulObjectFactory(MockBeanContainer container)
+ {
+ this.container = container;
+ }
+
+ public MockBeanContext create(Class[] initTypes, Object[] initValues)
+ {
+ MockBeanContext ctx = new MockBeanContext(container.getName());
+ ctx.setXPC(container.getXPC());
+
+ // Here we mock creating nested beans
+ for (MockBeanContainer childContainer : container.getChildren())
+ {
+ ctx.addChild(childContainer.getCache().create(null, null));
+ }
+
+ creationCount++;
+ return ctx;
+ }
+
+ public void destroy(MockBeanContext ctx)
+ {
+ ctx.remove();
+ destroyCount++;
+ }
+
+
+
+ public MockBeanContainer getContainer()
+ {
+ return container;
+ }
+
+ public int getCreationCount()
+ {
+ return creationCount;
+ }
+
+ public int getGroupCreationCount()
+ {
+ return groupCreationCount;
+ }
+
+ public int getDestroyCount()
+ {
+ return destroyCount;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/MockXPC.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.cache.mock;
+
+import java.io.Serializable;
+
+/**
+ * A mock extended PersistenceContext.
+ *
+ * @author Brian Stansberry
+ * @version $Revision$
+ */
+public class MockXPC implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ private boolean closed = false;
+ private MockEntity entity;
+
+ public MockEntity createEntity()
+ {
+ if (entity != null)
+ throw new IllegalStateException("entity already created");
+ entity = new MockEntity();
+ return entity;
+ }
+
+ public MockEntity getEntity()
+ {
+ return entity;
+ }
+
+ public void removeEntity()
+ {
+ if (entity == null)
+ throw new IllegalStateException("no entity to remove");
+ entity = null;
+ }
+
+ public boolean isClosed()
+ {
+ return closed;
+ }
+
+ public void close()
+ {
+ closed = true;
+ entity = null;
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransaction.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransaction.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransaction.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,142 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * 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, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.jboss.ejb3.test.cache.mock.tm;
+
+import java.util.LinkedList;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Mock Transaction implementation that works with DualNodeTransactionManagerImpl.
+ *
+ * @author Brian Stansberry
+ */
+public class MockTransaction implements Transaction
+{
+ private static final Logger log = Logger.getLogger(MockTransaction.class);
+
+ private int status;
+
+ private LinkedList<Synchronization> synchronizations;
+
+ private final MockTransactionManager jtaTransactionManager;
+
+ public MockTransaction(MockTransactionManager jtaTransactionManager)
+ {
+ this.jtaTransactionManager = jtaTransactionManager;
+ this.status = Status.STATUS_ACTIVE;
+ }
+
+ public int getStatus()
+ {
+ return status;
+ }
+
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+ IllegalStateException, SystemException
+ {
+
+ if (status == Status.STATUS_MARKED_ROLLBACK)
+ {
+ log.trace("on commit, status was marked for rollback-only");
+ rollback();
+ }
+ else
+ {
+ status = Status.STATUS_PREPARING;
+
+ for (int i = 0; i < synchronizations.size(); i++)
+ {
+ Synchronization s = (Synchronization) synchronizations.get(i);
+ s.beforeCompletion();
+ }
+
+ status = Status.STATUS_COMMITTING;
+
+ status = Status.STATUS_COMMITTED;
+
+ for (int i = 0; i < synchronizations.size(); i++)
+ {
+ Synchronization s = (Synchronization) synchronizations.get(i);
+ s.afterCompletion(status);
+ }
+
+ //status = Status.STATUS_NO_TRANSACTION;
+ jtaTransactionManager.endCurrent(this);
+ }
+ }
+
+ public void rollback() throws IllegalStateException, SystemException
+ {
+ status = Status.STATUS_ROLLEDBACK;
+
+ if (synchronizations != null)
+ {
+ for (int i = 0; i < synchronizations.size(); i++)
+ {
+ Synchronization s = (Synchronization) synchronizations.get(i);
+ s.afterCompletion(status);
+ }
+ }
+
+ //status = Status.STATUS_NO_TRANSACTION;
+ jtaTransactionManager.endCurrent(this);
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ status = Status.STATUS_MARKED_ROLLBACK;
+ }
+
+ public void registerSynchronization(Synchronization synchronization) throws RollbackException,
+ IllegalStateException, SystemException
+ {
+ // todo : find the spec-allowable statuses during which synch can be registered...
+ if (synchronizations == null)
+ {
+ synchronizations = new LinkedList<Synchronization>();
+ }
+ synchronizations.add(synchronization);
+ }
+
+ public boolean enlistResource(XAResource xaResource) throws RollbackException, IllegalStateException,
+ SystemException
+ {
+ return false;
+ }
+
+ public boolean delistResource(XAResource xaResource, int i) throws IllegalStateException, SystemException
+ {
+ return false;
+ }
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransactionManager.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransactionManager.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/cache/mock/tm/MockTransactionManager.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,183 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * 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, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.jboss.ejb3.test.cache.mock.tm;
+
+import java.util.Hashtable;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Variant of SimpleJtaTransactionManagerImpl that doesn't use a VM-singleton,
+ * but rather a set of impls keyed by a node id.
+ *
+ * @author Brian Stansberry
+ */
+public class MockTransactionManager implements TransactionManager
+{
+ public static final String DEFAULT = "default";
+
+ private static final Logger log = Logger.getLogger(MockTransactionManager.class);
+
+ private static final Hashtable<String, MockTransactionManager> INSTANCES = new Hashtable<String, MockTransactionManager>();
+
+ private ThreadLocal<MockTransaction> currentTransaction = new ThreadLocal<MockTransaction>();
+ private String nodeId;
+
+ public synchronized static MockTransactionManager getInstance()
+ {
+ return getInstance(DEFAULT);
+ }
+
+ public synchronized static MockTransactionManager getInstance(String nodeId)
+ {
+ MockTransactionManager tm = (MockTransactionManager) INSTANCES.get(nodeId);
+ if (tm == null)
+ {
+ tm = new MockTransactionManager(nodeId);
+ INSTANCES.put(nodeId, tm);
+ }
+ return tm;
+ }
+
+ public synchronized static void cleanupTransactions()
+ {
+ for (MockTransactionManager tm : INSTANCES.values())
+ {
+ try
+ {
+ tm.currentTransaction.remove();
+ }
+ catch (Exception e)
+ {
+ log.error("Exception cleaning up TransactionManager " + tm);
+ }
+ }
+ }
+
+ public synchronized static void cleanupTransactionManagers()
+ {
+ INSTANCES.clear();
+ }
+
+ private MockTransactionManager(String nodeId)
+ {
+ this.nodeId = nodeId;
+ }
+
+ public int getStatus() throws SystemException
+ {
+ return currentTransaction.get() == null ? Status.STATUS_NO_TRANSACTION : currentTransaction.get().getStatus();
+ }
+
+ public Transaction getTransaction() throws SystemException
+ {
+ return currentTransaction.get();
+ }
+
+ public MockTransaction getCurrentTransaction()
+ {
+ return currentTransaction.get();
+ }
+
+ public void begin() throws NotSupportedException, SystemException
+ {
+ currentTransaction.set(new MockTransaction(this));
+ }
+
+ public Transaction suspend() throws SystemException
+ {
+ log
+ .trace(nodeId + ": Suspending " + currentTransaction.get() + " for thread "
+ + Thread.currentThread().getName());
+ MockTransaction suspended = currentTransaction.get();
+ currentTransaction.set(null);
+ return suspended;
+ }
+
+ public void resume(Transaction transaction) throws InvalidTransactionException, IllegalStateException,
+ SystemException
+ {
+ currentTransaction.set((MockTransaction) transaction);
+ log.trace(nodeId + ": Resumed " + transaction + " for thread " + Thread.currentThread().getName());
+ }
+
+ public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
+ SecurityException, IllegalStateException, SystemException
+ {
+ if (currentTransaction.get() == null)
+ {
+ throw new IllegalStateException("no current transaction to commit");
+ }
+ currentTransaction.get().commit();
+ }
+
+ public void rollback() throws IllegalStateException, SecurityException, SystemException
+ {
+ if (currentTransaction.get() == null)
+ {
+ throw new IllegalStateException("no current transaction");
+ }
+ currentTransaction.get().rollback();
+ }
+
+ public void setRollbackOnly() throws IllegalStateException, SystemException
+ {
+ if (currentTransaction.get() == null)
+ {
+ throw new IllegalStateException("no current transaction");
+ }
+ currentTransaction.get().setRollbackOnly();
+ }
+
+ public void setTransactionTimeout(int i) throws SystemException
+ {
+ }
+
+ void endCurrent(MockTransaction transaction)
+ {
+ if (transaction == currentTransaction.get())
+ {
+ currentTransaction.set(null);
+ }
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer(getClass().getName());
+ sb.append("[nodeId=");
+ sb.append(nodeId);
+ sb.append("]");
+ return sb.toString();
+ }
+}
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/GroupedPassivatingUnitTestCase.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/GroupedPassivatingUnitTestCase.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/GroupedPassivatingUnitTestCase.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -21,17 +21,14 @@
*/
package org.jboss.ejb3.test.distributed;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
import junit.framework.TestCase;
-import org.jboss.ejb3.cache.PassivationManager;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-import org.jboss.ejb3.cache.grouped.SerializationGroup;
-import org.jboss.ejb3.cache.impl.SerializationGroupContainer;
-import org.jboss.ejb3.cache.impl.SimplePassivatingCache2;
+import org.jboss.ejb3.test.cache.mock.CacheType;
+import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
+import org.jboss.ejb3.test.cache.mock.MockBeanContext;
+import org.jboss.ejb3.test.cache.mock.MockCacheConfig;
+import org.jboss.ejb3.test.cache.mock.MockPassivationManager;
+import org.jboss.ejb3.test.cache.mock.MockXPC;
import org.jboss.logging.Logger;
/**
@@ -56,76 +53,72 @@
}
}
- public void test1()
+ public void testSimpleGroupPassivation() throws Exception
{
- Map<Object, Object> localJBC = new HashMap<Object, Object>();
- Map<Object, Object> remoteJBC = new HashMap<Object, Object>();
- SerializationGroupContainer container = new SerializationGroupContainer();
- StatefulObjectFactory<SerializationGroup> factory = container;
- PassivationManager<SerializationGroup> passivationManager = container;
- MockJBCIntegratedObjectStore<SerializationGroup> store = new MockJBCIntegratedObjectStore<SerializationGroup>(localJBC, remoteJBC);
- SimplePassivatingCache2<SerializationGroup> groupCache = new SimplePassivatingCache2<SerializationGroup>(factory, passivationManager, store);
- MockBeanContainer container1 = new MockBeanContainer("MockBeanContainer1", 1, groupCache, localJBC, remoteJBC);
- MockBeanContainer container2 = new MockBeanContainer("MockBeanContainer2", 10, groupCache, localJBC, remoteJBC);
+ MockCluster cluster = new MockCluster(false);
+ MockClusterMember node0 = cluster.getNode0();
+ MockCacheConfig cacheConfig = new MockCacheConfig();
+ cacheConfig.setIdleTimeoutSeconds(1);
+ MockXPC sharedXPC = new MockXPC();
+ MockBeanContainer container1 = node0.deployBeanContainer("MockBeanContainer1", null, CacheType.DISTRIBUTED, cacheConfig, sharedXPC);
+ MockBeanContainer container2 = node0.deployBeanContainer("MockBeanContainer2", "MockBeanContainer1", CacheType.DISTRIBUTED, cacheConfig, sharedXPC);
+ cluster.getNode0().setTCCL();
try
{
- groupCache.start();
- container1.start();
- container2.start();
-
- Object shared = new SharedObject();
+ Object key1 = container1.getCache().create(null, null).getId();
MockBeanContext firstCtx1;
- MockBeanContext ctx1 = firstCtx1 = container1.getCache().create(null, null);
- Object key1 = ctx1.getId();
- // We assign the shared object here as if it were an XPC injected
- // during SFSB creation
- ctx1.shared = shared;
- MockBeanContext ctx2 = container2.getCache().create(null, null);
- Object key2 = ctx2.getId();
- ctx2.shared = shared;
+ MockBeanContext ctx1 = firstCtx1 = container1.getCache().get(key1);
- // TODO: how will passivation groups be created?
- SerializationGroup group = groupCache.create(null, null);
- container1.getCache().setGroup(ctx1, group);
- container2.getCache().setGroup(ctx2, group);
- // TODO: currently we need to release the group
- // BES -- not any more
- // groupCache.release(group);
+ Object key2 = ctx1.getChild(container2.getName());
+ MockBeanContext ctx2 = container2.getCache().get(key2);
- container1.getCache().release(ctx1);
- container2.getCache().release(ctx2);
+ assertNotNull(ctx1.getXPC());
+ assertEquals(ctx1.getXPC(), ctx2.getXPC());
- sleep(4000);
+ container2.getCache().finished(ctx2);
+ container1.getCache().finished(ctx1);
- assertEquals("ctx1 should have been passivated", 1, container1.passivations);
- assertEquals("ctx2 should have been passivated", 1, container2.passivations);
+ sleep(2100);
+ MockPassivationManager pass1 = (MockPassivationManager) container1.getPassivationManager();
+ MockPassivationManager pass2 = (MockPassivationManager) container2.getPassivationManager();
+
+ assertEquals("ctx1 should have been passivated", 1, pass1.getPrePassivateCount());
+ assertEquals("ctx2 should have been passivated", 1, pass2.getPrePassivateCount());
+
ctx2 = container2.getCache().get(key2);
log.info("ctx2 = " + ctx2);
assertNotNull(ctx2);
- assertEquals("ctx2 should have been postReplicated", 1, container2.postReplications);
- assertEquals("ctx2 should have been activated", 1, container2.activations);
+ assertEquals("ctx2 should not have been postReplicated", 0, pass2.getPostReplicateCount());
+ assertEquals("ctx2 should have been activated", 1, pass2.getPostActivateCount());
ctx1 = container1.getCache().get(key1);
log.info("ctx1 = " + ctx1);
assertNotNull(ctx1);
- assertEquals("ctx1 should have been postReplicated", 1, container1.postReplications);
- assertEquals("ctx1 should have been activated", 1, container1.activations);
+ assertEquals("ctx1 should not have been postReplicated", 0, pass1.getPostReplicateCount());
+ assertEquals("ctx1 should have been activated", 1, pass1.getPostActivateCount());
assertTrue("ctx1 must be different than firstCtx1 (else no passivation has taken place)", ctx1 != firstCtx1);
- assertEquals(ctx1.shared, ctx2.shared);
+ assertNotNull(ctx1.getXPC());
+ assertEquals(ctx1.getXPC(), ctx2.getXPC());
}
finally
{
- container1.stop();
- container2.stop();
- groupCache.stop();
+ try
+ {
+ container1.stop();
+ container2.stop();
+ }
+ finally
+ {
+ cluster.getNode0().restoreTCCL();
+ }
}
}
}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContainer.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContainer.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContainer.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,137 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.test.distributed;
-
-import java.util.Map;
-
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.PassivationManager;
-import org.jboss.ejb3.cache.StatefulObjectFactory;
-import org.jboss.ejb3.cache.grouped.GroupedPassivatingCache;
-import org.jboss.ejb3.cache.grouped.SerializationGroup;
-import org.jboss.ejb3.cache.impl.GroupedPassivatingCacheImpl2;
-import org.jboss.ejb3.cache.impl.SerializationGroupMemberImpl;
-import org.jboss.logging.Logger;
-
-/**
- * Comment
- *
- * @author Brian Stansberry
- * @version $Revision: 65920 $
- */
-public class MockBeanContainer implements StatefulObjectFactory<MockBeanContext>, PassivationManager<MockBeanContext>
-{
- private static final Logger log = Logger.getLogger(MockBeanContainer.class);
-
- protected int activations = 0;
- protected int passivations = 0;
- protected int preReplications = 0;
- protected int postReplications = 0;
-
- private GroupedPassivatingCache<MockBeanContext> cache;
-
- public MockBeanContainer(String name, int sessionTimeout, PassivatingCache<SerializationGroup> groupCache, Map<Object, Object> localJBC, Map<Object, Object> remoteJBC)
- {
- MockJBCIntegratedObjectStore<SerializationGroupMemberImpl<MockBeanContext>> store = new MockJBCIntegratedObjectStore<SerializationGroupMemberImpl<MockBeanContext>>(localJBC, remoteJBC);
- store.setIdleTimeSeconds(sessionTimeout);
- store.setInterval(1);
- this.cache = new GroupedPassivatingCacheImpl2<MockBeanContext>(this, this, store, groupCache);
- }
-
- public MockBeanContext create(Class<?>[] initTypes, Object[] initValues)
- {
- return new MockBeanContext();
- }
-
- public GroupedPassivatingCache<MockBeanContext> getCache()
- {
- return cache;
- }
-
- public void destroy(MockBeanContext obj)
- {
- }
-
- public void postActivate(MockBeanContext obj)
- {
- if(obj == null) throw new IllegalArgumentException("obj is null");
-
- log.info("postActivate " + obj);
- activations++;
- synchronized(this)
- {
- notifyAll();
- }
- }
-
- public void prePassivate(MockBeanContext obj)
- {
- if(obj == null) throw new IllegalArgumentException("obj is null");
-
- log.info("prePassivate " + obj);
- passivations++;
- synchronized(this)
- {
- notifyAll();
- }
- }
-
- public boolean isClustered()
- {
- return true;
- }
-
- public void postReplicate(MockBeanContext obj)
- {
- if(obj == null) throw new IllegalArgumentException("obj is null");
-
- log.info("postReplicate " + obj);
- postReplications++;
- synchronized(this)
- {
- notifyAll();
- }
- }
-
- public void preReplicate(MockBeanContext obj)
- {
- if(obj == null) throw new IllegalArgumentException("obj is null");
-
- log.info("preReplicate " + obj);
- preReplications++;
- synchronized(this)
- {
- notifyAll();
- }
- }
-
- public void start()
- {
- cache.start();
- }
-
- public void stop()
- {
- cache.stop();
- }
-
-}
Deleted: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContext.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContext.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockBeanContext.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -1,79 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, Red Hat Middleware LLC, and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.test.distributed;
-
-import java.io.Serializable;
-
-import org.jboss.ejb3.cache.Cacheable;
-
-/**
- * Comment
- *
- * @author Brian Stansberry
- * @version $Revision: 65339 $
- */
-public class MockBeanContext implements Cacheable, Serializable
-{
- private static final long serialVersionUID = 1L;
-
- private static volatile long currentId = 100000;
-
- private long id;
-
- private boolean inUse;
- private long lastUsed;
-
- public Object shared;
-
- public MockBeanContext()
- {
- this.id = ++currentId;
- }
-
- public Object getId()
- {
- return id;
- }
-
- public boolean isInUse()
- {
- return inUse;
- }
-
- public void setInUse(boolean inUse)
- {
- this.inUse = inUse;
- lastUsed = System.currentTimeMillis();
- }
-
- public long getLastUsed()
- {
- return lastUsed;
- }
-
- @Override
- public String toString()
- {
- return super.toString() + "{id=" + id + "}";
- }
-
-}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockCluster.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockCluster.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockCluster.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,117 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.distributed;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.test.cache.mock.CacheType;
+import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
+import org.jboss.ejb3.test.cache.mock.MockCacheConfig;
+import org.jboss.ejb3.test.cache.mock.MockXPC;
+import org.jboss.ejb3.test.cache.mock.tm.MockTransactionManager;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockCluster
+{
+ private TransactionManager tm0;
+ private TransactionManager tm1;
+ private UnmarshallingMap map0;
+ private UnmarshallingMap map1;
+ private MockClusterMember node0;
+ private MockClusterMember node1;
+
+ public MockCluster(boolean useCoordinator)
+ {
+ this(MockTransactionManager.getInstance("node0"),
+ MockTransactionManager.getInstance("node1"),
+ useCoordinator, CacheType.DISTRIBUTED);
+ }
+
+ public MockCluster(TransactionManager tm0, TransactionManager tm1, boolean useCoordinator, CacheType cacheType)
+ {
+ this(tm0, tm1, useCoordinator, new CacheType[] { cacheType});
+ }
+
+ public MockCluster(TransactionManager tm0, TransactionManager tm1, boolean useCoordinator, CacheType[] availableTypes)
+ {
+ this.tm0 = tm0;
+ this.tm1 = tm1;
+
+ map0 = new UnmarshallingMap();
+ map1 = new UnmarshallingMap();
+
+ node0 = new MockClusterMember(tm0, useCoordinator, availableTypes, map0, map1);
+ node1 = new MockClusterMember(tm1, useCoordinator, availableTypes, map1, map0);
+ }
+
+ public TransactionManager getTm0()
+ {
+ return tm0;
+ }
+
+ public TransactionManager getTm1()
+ {
+ return tm1;
+ }
+
+ public UnmarshallingMap getMap0()
+ {
+ return map0;
+ }
+
+ public UnmarshallingMap getMap1()
+ {
+ return map1;
+ }
+
+ public MockClusterMember getNode0()
+ {
+ return node0;
+ }
+
+ public MockClusterMember getNode1()
+ {
+ return node1;
+ }
+
+ public MockBeanContainer[] deployBeanContainer(String containerName, String parentContainerName,
+ CacheType cacheType, MockCacheConfig cacheConfig, boolean useXPC) throws Exception
+ {
+ MockXPC xpc0 = useXPC ? new MockXPC() : null;
+ MockXPC xpc1 = useXPC ? new MockXPC() : null;
+ return deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc0, xpc1);
+ }
+
+ public MockBeanContainer[] deployBeanContainer(String containerName, String parentContainerName,
+ CacheType cacheType, MockCacheConfig cacheConfig, MockXPC xpc0, MockXPC xpc1) throws Exception
+ {
+ MockBeanContainer[] result = new MockBeanContainer[2];
+ result[0] = node0.deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc0);
+ result[1] = node1.deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc1);
+ return result;
+ }
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockClusterMember.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockClusterMember.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockClusterMember.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,152 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.distributed;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
+import org.jboss.ejb3.test.cache.mock.CacheType;
+import org.jboss.ejb3.test.cache.mock.MockBeanContainer;
+import org.jboss.ejb3.test.cache.mock.MockBeanContext;
+import org.jboss.ejb3.test.cache.mock.MockCacheConfig;
+import org.jboss.ejb3.test.cache.mock.MockEjb3System;
+import org.jboss.ejb3.test.cache.mock.MockXPC;
+
+/**
+ * @author Brian Stansberry
+ */
+public class MockClusterMember extends MockEjb3System
+{
+ private UnmarshallingMap localDistributedCacheMember;
+ private UnmarshallingMap remoteDistributedCacheMember;
+ private ClassLoader localClassLoader;
+
+ public MockClusterMember(TransactionManager tm,
+ boolean useCoordinator,
+ CacheType cacheType,
+ UnmarshallingMap local,
+ UnmarshallingMap remote)
+ {
+ this(tm, useCoordinator, new CacheType[] {cacheType}, local, remote);
+ }
+
+ public MockClusterMember(TransactionManager tm,
+ boolean useCoordinator,
+ CacheType[] availableTypes,
+ UnmarshallingMap local,
+ UnmarshallingMap remote)
+ {
+ super(tm, useCoordinator, availableTypes);
+ this.localDistributedCacheMember = local;
+ this.remoteDistributedCacheMember =remote;
+
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ localClassLoader = new ClassLoader(tccl) {};
+
+ // Kluge. Rebuild the distributed factory, as the superclass
+ // didn't have the maps available when it did it
+ for (CacheType type : availableTypes)
+ {
+ if (type == CacheType.DISTRIBUTED)
+ getCacheFactoryRegistry().addCacheFactory(type.mapKey(), buildCacheFactory(type));
+ }
+ }
+
+ public UnmarshallingMap getLocalDistributedCacheMember()
+ {
+ return localDistributedCacheMember;
+ }
+
+ public UnmarshallingMap getRemoteDistributedCacheMember()
+ {
+ return remoteDistributedCacheMember;
+ }
+
+ public ClassLoader getLocalClassLoader()
+ {
+ return localClassLoader;
+ }
+
+ public boolean setTCCL()
+ {
+ if (localClassLoader == Thread.currentThread().getContextClassLoader())
+ return false;
+ Thread.currentThread().setContextClassLoader(localClassLoader);
+ return true;
+ }
+
+ public void restoreTCCL()
+ {
+ ClassLoader current = Thread.currentThread().getContextClassLoader();
+ if (current == localClassLoader)
+ {
+ Thread.currentThread().setContextClassLoader(localClassLoader.getParent());
+ }
+ else if (current != localClassLoader.getParent())
+ {
+ throw new IllegalStateException("Current TCCL is neither localClassLoader nor its parent");
+ }
+ }
+
+ @Override
+ protected IntegratedObjectStoreSource<MockBeanContext> getDistributedStoreSource()
+ {
+ return new MockIntegratedObjectStoreSource<MockBeanContext>(localDistributedCacheMember,
+ remoteDistributedCacheMember);
+ }
+
+ @Override
+ public MockBeanContainer deployBeanContainer(String containerName, String parentContainerName,
+ CacheType cacheType, MockCacheConfig cacheConfig, MockXPC xpc) throws Exception
+ {
+ boolean tcclSet = setTCCL();
+ try
+ {
+ return super.deployBeanContainer(containerName, parentContainerName, cacheType, cacheConfig, xpc);
+ }
+ finally
+ {
+ if (tcclSet)
+ restoreTCCL();
+ }
+ }
+
+ @Override
+ public MockBeanContainer getMockBeanContainer(String containerName)
+ {
+ boolean tcclSet = setTCCL();
+ try
+ {
+ return super.getMockBeanContainer(containerName);
+ }
+ finally
+ {
+ if (tcclSet)
+ restoreTCCL();
+ }
+ }
+
+
+
+
+}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockIntegratedObjectStoreSource.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockIntegratedObjectStoreSource.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockIntegratedObjectStoreSource.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.distributed;
+
+import javax.transaction.TransactionManager;
+
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStoreSource;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupImpl;
+import org.jboss.ejb3.cache.spi.impl.SerializationGroupMember;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockIntegratedObjectStoreSource<T extends CacheItem>
+ implements IntegratedObjectStoreSource<T>
+{
+ private UnmarshallingMap localMap;
+ private UnmarshallingMap remoteMap;
+
+ public MockIntegratedObjectStoreSource(UnmarshallingMap localMap, UnmarshallingMap remoteMap)
+ {
+ this.localMap = localMap;
+ this.remoteMap = remoteMap;
+ }
+
+ public PassivatingIntegratedObjectStore<T, SerializationGroupImpl<T>> createGroupIntegratedObjectStore(String containerName,
+ String cacheConfigName, CacheConfig cacheConfig, TransactionManager transactionManager)
+ {
+ String keyBase = "GroupCache-" + containerName;
+ return new MockJBCIntegratedObjectStore<T, SerializationGroupImpl<T>>(localMap, remoteMap, cacheConfig, keyBase, keyBase);
+ }
+
+ public PassivatingIntegratedObjectStore<T, SerializationGroupMember<T>> createIntegratedObjectStore(String containerName, String cacheConfigName,
+ CacheConfig cacheConfig, TransactionManager transactionManager)
+ {
+ return new MockJBCIntegratedObjectStore<T, SerializationGroupMember<T>>(localMap, remoteMap, cacheConfig, containerName, containerName);
+ }
+
+}
Modified: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockJBCIntegratedObjectStore.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockJBCIntegratedObjectStore.java 2008-03-11 04:27:06 UTC (rev 70719)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/MockJBCIntegratedObjectStore.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -22,12 +22,9 @@
package org.jboss.ejb3.test.distributed;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -36,12 +33,14 @@
import java.util.SortedSet;
import java.util.TreeSet;
-import org.jboss.ejb3.cache.Cacheable;
-import org.jboss.ejb3.cache.IntegratedObjectStore;
-import org.jboss.ejb3.cache.ItemInUseException;
-import org.jboss.ejb3.cache.PassivatingCache;
-import org.jboss.ejb3.cache.PassivatingIntegratedObjectStore;
-import org.jboss.ejb3.cache.impl.CacheableTimestamp;
+import org.jboss.ejb3.annotation.CacheConfig;
+import org.jboss.ejb3.cache.CacheItem;
+import org.jboss.ejb3.cache.spi.BackingCacheEntry;
+import org.jboss.ejb3.cache.spi.IntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.PassivatingBackingCache;
+import org.jboss.ejb3.cache.spi.PassivatingIntegratedObjectStore;
+import org.jboss.ejb3.cache.spi.impl.CacheableTimestamp;
+import org.jboss.ejb3.cache.spi.impl.PassivationExpirationRunner;
import org.jboss.logging.Logger;
/**
@@ -51,54 +50,69 @@
* @author Brian Stansberry
* @version $Revision$
*/
-public class MockJBCIntegratedObjectStore<T extends Cacheable & Serializable>
- implements PassivatingIntegratedObjectStore<T>
+public class MockJBCIntegratedObjectStore<C extends CacheItem, T extends BackingCacheEntry<C>>
+ implements PassivatingIntegratedObjectStore<C, T>
{
private static final Logger log = Logger.getLogger(MockJBCIntegratedObjectStore.class);
+ /**
+ * Qualifier used to scope our keys in the maps
+ */
+ private final Object keyBase;
+
/**
* Our in-VM "JBoss Cache" instance.
*/
- private Map<Object, Object> localJBC;
+ private final UnmarshallingMap localJBC;
/**
* A remote "JBoss Cache" instance. We only store byte[] values,
* mocking the effect of replication.
*/
- private Map<Object, Object> remoteJBC;
+ private final UnmarshallingMap remoteJBC;
/**
* Those keys in the mockJBC map that haven't been "passivated"
*/
- private Set<Object> inMemory;
+ private final Set<Object> inMemory;
/**
* Those keys that have been updated locally but not copied to remoteJBC.
*/
private Set<Object> dirty;
- private Map<Object, Long> timestamps;
+ private final Map<Object, Long> timestamps;
/** A mock transaction manager */
- private ThreadLocal<Boolean> tm = new ThreadLocal<Boolean>();
+ private final ThreadLocal<Boolean> tm = new ThreadLocal<Boolean>();
/**
* Support callbacks when our MockEvictionRunner decides to
* evict an entry.
*/
- private PassivatingCache<T> owningCache;
+ private PassivatingBackingCache<C, T> owningCache;
private int interval;
- private int idleTimeSeconds;
- private int expirationTimeSeconds;
+ private long idleTimeSeconds;
+ private long expirationTimeSeconds;
+ private int maxSize;
+ private PassivationExpirationRunner sessionTimeoutRunner;
+ private final String name;
+ private boolean stopped = true;
- private SessionTimeoutRunner sessionTimeoutRunner;
-
- public MockJBCIntegratedObjectStore(Map<Object, Object> localCache,
- Map<Object, Object> remoteCache)
+ public MockJBCIntegratedObjectStore(UnmarshallingMap localCache,
+ UnmarshallingMap remoteCache,
+ CacheConfig cacheConfig,
+ Object keyBase,
+ String name)
{
this.localJBC = localCache;
this.remoteJBC = remoteCache;
+ this.keyBase = keyBase;
inMemory = new HashSet<Object>();
timestamps = new HashMap<Object, Long>();
+ this.idleTimeSeconds = cacheConfig.idleTimeoutSeconds();
+ this.expirationTimeSeconds = cacheConfig.removalTimeoutSeconds();
+ this.maxSize = cacheConfig.maxSize();
+ this.name = name;
}
// -------------------------------------------------- IntegratedObjectStore
@@ -109,9 +123,10 @@
}
public T get(Object key)
- {
- T entry = unmarshall(key, localJBC.get(key));
- timestamps.put(key, new Long(System.currentTimeMillis()));
+ {
+ T entry = unmarshall(key, localJBC.get(getScopedKey(key)));
+ if (entry != null)
+ timestamps.put(key, new Long(System.currentTimeMillis()));
return entry;
}
@@ -122,7 +137,10 @@
public void update(T entry)
{
- putInCache(entry.getId(), entry);
+ if (entry.isModified())
+ {
+ putInCache(entry.getId(), entry);
+ }
}
@SuppressWarnings("unchecked")
@@ -132,7 +150,8 @@
if (inMemory.contains(key))
{
log.trace("converting " + key + " to passivated state");
- localJBC.put(key, marshall((T) localJBC.get(key)));
+ ScopedKey skey = getScopedKey(key);
+ localJBC.put(skey, marshall((T) localJBC.get(skey)));
inMemory.remove(key);
}
}
@@ -159,7 +178,7 @@
for (Iterator<Object> iter = dirty.iterator(); iter.hasNext();)
{
Object key = iter.next();
- replicate(key, unmarshall(key, localJBC.get(key)));
+ replicate(key, unmarshall(key, localJBC.get(getScopedKey(key))));
iter.remove();
}
}
@@ -172,39 +191,30 @@
@SuppressWarnings("unchecked")
private T unmarshall(Object key, Object obj)
{
- if (obj == null)
- return null;
- else if (!(obj instanceof byte[]))
+ if (!(obj instanceof byte[]))
return (T) obj;
log.trace("unmarshalling " + key);
- ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) obj);
- try
- {
- ObjectInputStream ois = new ObjectInputStream(bais);
- T entry = (T) ois.readObject();
- localJBC.put(key, entry);
- inMemory.add(key);
- return entry;
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
+ ScopedKey skey = getScopedKey(key);
+ T entry = (T) localJBC.unmarshall(skey);
+ localJBC.put(skey, entry);
+ inMemory.add(key);
+ return entry;
}
private Object putInCache(Object key, T value)
{
+ ScopedKey skey = getScopedKey(key);
Object existing = null;
if (value != null)
{
- existing = localJBC.put(key, value);
+ existing = localJBC.put(skey, value);
inMemory.add(key);
timestamps.put(key, new Long(System.currentTimeMillis()));
}
else
{
- existing = localJBC.remove(key);
+ existing = localJBC.remove(skey);
inMemory.remove(key);
timestamps.remove(key);
}
@@ -223,10 +233,11 @@
private void replicate(Object key, T value)
{
+ ScopedKey skey = getScopedKey(key);
if (value != null)
- remoteJBC.put(key, marshall(value));
+ remoteJBC.put(skey, marshall(value));
else
- remoteJBC.remove(key);
+ remoteJBC.remove(skey);
}
private byte[] marshall(T value)
@@ -273,9 +284,10 @@
remove(ts.getId());
}
}
- catch (ItemInUseException ignored)
+ catch (IllegalStateException ise)
{
- log.trace("skipping in-use entry " + ts.getId());
+ // Not so great; we're assuming it's 'cause item's in use
+ log.trace("skipping in-use entry " + ts.getId(), ise);
}
}
}
@@ -288,27 +300,31 @@
long now = System.currentTimeMillis();
long minPassUse = now - (idleTimeSeconds * 1000);
- // Scan the in-memory entries for passivation or removal
- for (CacheableTimestamp ts : getInMemoryEntries())
+ SortedSet<CacheableTimestamp> timestamps = getInMemoryEntries();
+ int overCount = timestamps.size() - maxSize;
+ for (CacheableTimestamp ts : timestamps)
{
try
{
long lastUsed = ts.getLastUsed();
- if (minPassUse >= lastUsed)
+ if (overCount > 0 || minPassUse >= lastUsed)
{
+ log.trace("attempting to passivate " + ts.getId());
owningCache.passivate(ts.getId());
+ overCount--;
}
}
- catch (ItemInUseException ignored)
+ catch (IllegalStateException ise)
{
- log.trace("skipping in-use entry " + ts.getId());
+ // Not so great; we're assuming it's 'cause item's in use
+ log.trace("skipping in-use entry " + ts.getId(), ise);
}
}
}
}
- public void setPassivatingCache(PassivatingCache<T> cache)
+ public void setPassivatingCache(PassivatingBackingCache<C, T> cache)
{
this.owningCache = cache;
}
@@ -319,10 +335,17 @@
{
if (sessionTimeoutRunner == null)
{
- sessionTimeoutRunner = new SessionTimeoutRunner();
+ assert name != null : "name has not been set";
+ assert owningCache != null;
+ String timerName = "PassivationExpirationTimer-" + name;
+ sessionTimeoutRunner = new PassivationExpirationRunner(this, timerName, interval);
}
sessionTimeoutRunner.start();
- }
+ }
+
+ stopped = false;
+
+ log.debug("Started " + name);
}
public void stop()
@@ -330,25 +353,29 @@
if (sessionTimeoutRunner != null)
{
sessionTimeoutRunner.stop();
- }
+ }
+
+ stopped = true;
+
+ log.debug("Stopped " + name);
}
- public int getIdleTimeSeconds()
+ public long getIdleTimeSeconds()
{
return idleTimeSeconds;
}
- public void setIdleTimeSeconds(int idleTimeSeconds)
+ public void setIdleTimeSeconds(long idleTimeSeconds)
{
this.idleTimeSeconds = idleTimeSeconds;
}
- public int getExpirationTimeSeconds()
+ public long getExpirationTimeSeconds()
{
return expirationTimeSeconds;
}
- public void setExpirationTimeSeconds(int timeout)
+ public void setExpirationTimeSeconds(long timeout)
{
this.expirationTimeSeconds = timeout;
}
@@ -376,77 +403,73 @@
return set;
}
-
- private class SessionTimeoutRunner implements Runnable
+
+ public boolean isPassivationExpirationSelfManaged()
{
- private boolean stopped = true;
- private Thread thread;
-
- public void run()
+ return interval > 0;
+ }
+
+ public void processPassivationExpiration()
+ {
+ try
{
- while (!stopped)
- {
- try
- {
- runPassivation();
- }
- catch (Exception e)
- {
- log.error("Caught exception processing passivations", e);
- }
-
- if (!stopped)
- {
- try
- {
- runExpiration();
- }
- catch (Exception e)
- {
- log.error("Caught exception processing expirations", e);
- }
- }
-
- if (!stopped)
- {
- try
- {
- Thread.sleep(interval * 1000);
- }
- catch (InterruptedException ignored) {}
- }
- }
+ runPassivation();
}
+ catch (Exception e)
+ {
+ log.error("Caught exception processing passivations", e);
+ }
- void start()
+ if (!stopped)
{
- if (stopped)
+ try
{
- thread = new Thread(this, "MockEvictionThread");
- thread.setDaemon(true);
- stopped = false;
- thread.start();
+ runExpiration();
}
+ catch (Exception e)
+ {
+ log.error("Caught exception processing expirations", e);
+ }
}
+ }
+
+ private ScopedKey getScopedKey(Object unscoped)
+ {
+ return new ScopedKey(unscoped, keyBase);
+ }
+
+ private static class ScopedKey
+ {
+ private Object unscoped;
+ private Object keyBase;
+ ScopedKey(Object unscoped, Object keyBase)
+ {
+ this.unscoped = unscoped;
+ this.keyBase = keyBase;
+ }
- void stop()
+ @Override
+ public int hashCode()
{
- stopped = true;
- if (thread != null && thread.isAlive())
+ int result = 17;
+ result += 31 * unscoped.hashCode();
+ result += 31 * keyBase.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+
+ if (obj instanceof ScopedKey)
{
- try
- {
- thread.join(1000);
- }
- catch (InterruptedException ignored) {}
-
- if (thread.isAlive())
- {
- thread.interrupt();
- }
-
+ ScopedKey other = (ScopedKey) obj;
+ return (this.unscoped.equals(other.unscoped)
+ && keyBase.equals(other.keyBase));
}
+ return false;
}
-
}
}
Added: projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/UnmarshallingMap.java
===================================================================
--- projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/UnmarshallingMap.java (rev 0)
+++ projects/ejb3/branches/cluster-dev/ejb3-cache/src/test/java/org/jboss/ejb3/test/distributed/UnmarshallingMap.java 2008-03-11 04:27:49 UTC (rev 70720)
@@ -0,0 +1,98 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ejb3.test.distributed;
+
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Brian Stansberry
+ */
+public class UnmarshallingMap extends HashMap<Object, Object>
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = -5305256519983822837L;
+
+ /**
+ * Create a new UnmarshallingMap.
+ *
+ */
+ public UnmarshallingMap()
+ {
+ super();
+ }
+
+ /**
+ * Create a new UnmarshallingMap.
+ *
+ * @param initialCapacity
+ */
+ public UnmarshallingMap(int initialCapacity)
+ {
+ super(initialCapacity);
+ }
+
+ /**
+ * Create a new UnmarshallingMap.
+ *
+ * @param m
+ */
+ public UnmarshallingMap(Map<Object, Object> m)
+ {
+ super(m);
+ }
+
+ /**
+ * Create a new UnmarshallingMap.
+ *
+ * @param initialCapacity
+ * @param loadFactor
+ */
+ public UnmarshallingMap(int initialCapacity, float loadFactor)
+ {
+ super(initialCapacity, loadFactor);
+ }
+
+ public Object unmarshall(Object key)
+ {
+ Object value = get(key);
+ if (value instanceof byte[])
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) value);
+ try
+ {
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ value = ois.readObject();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ return value;
+ }
+
+}
More information about the jboss-cvs-commits
mailing list