[jbosscache-commits] JBoss Cache SVN: r5151 - in pojo/trunk/src: main/java/org/jboss/cache/pojo and 2 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Jan 16 17:17:11 EST 2008


Author: jason.greene at jboss.com
Date: 2008-01-16 17:17:11 -0500 (Wed, 16 Jan 2008)
New Revision: 5151

Added:
   pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java
   pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java
Modified:
   pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml
   pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java
   pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java
   pojo/trunk/src/test/java/org/jboss/cache/pojo/BuddyReplicationTest.java
Log:
Merge 5150 and 5149


Modified: pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml
===================================================================
--- pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml	2008-01-16 22:15:37 UTC (rev 5150)
+++ pojo/trunk/src/main/docbook/userguide/en/modules/instrumentation.xml	2008-01-16 22:17:11 UTC (rev 5151)
@@ -7,7 +7,7 @@
   approach since it preserves object identity and provides field granular
   replication. POJO Cache currently uses the JBoss AOP project to provide
   instrumentation, so the same processes described in the AOP documentation
-  can be used with POJO Cache.</para>
+  are used with POJO Cache.</para>
 
   <para>The primary input to JBoss AOP is the AOP binding file, which is
   responsible for specifying which classes should be instrumented. POJO Cache
@@ -57,86 +57,74 @@
    &lt;jvmarg value="-Djboss.aop.path=etc/META-INF/pojocache-aop.xml"/&gt;
    &lt;classpath refid="test.classpath"/&gt;
 &lt;/java&gt;      </programlisting>
+
+    <para>Once the JVM is executed in this manner, any class with the
+    <literal>@Replicable</literal> annotation will be instrumented when it is
+    loaded.</para>
   </sect1>
 
-  <para>For the first step, since we are using the dynamic Aop feature, a POJO
-  is only required to be declared "prepare". Basically, there are two ways to
-  do this: either via explicit xml or annotation.</para>
+  <sect1>
+    <title>Compile-time instrumentation</title>
 
-  <para>As for the second step, either we can ask JBoss Aop to do load-time
-  (through a special class loader, so-called load-time mode) or compile-time
-  instrumentation (use of an aopc pre-compiler, so-called precompiled mode).
-  Reader can read the JBoss Aop introduction chapter for more details.</para>
+    <para>While load-time is the preffered approach, it is also possible to
+    instrument classes at compile-time. To do this, the aopc tool is used,
+    with the following requirements:</para>
 
-  <sect1><title>XML descriptor</title> <para> To declare a POJO via XML
-  configuration file, you will need a
-  <literal>META-INF/jboss-aop.xml</literal> (or in the PojoCache case, it is
-  the equivalent <literal>pojocache-service.xml</literal> file located under
-  the class path or listed in the <literal>jboss.aop.path</literal> system
-  property. JBoss AOP framework will read this file during startup to make
-  necessary byte code manipulation for advice and introduction. Or you can
-  pre-compile it using a pre-compiler called <literal>aopc</literal> such that
-  you won't need the XML file during load time. JBoss Aop provides a so-called
-  <literal>pointcut</literal> language where it consists of a regular
-  expression set to specify the interception points (or
-  <literal>jointpoint</literal> in aop parlance). The jointpoint can be
-  constructor, method call, or field. You will need to declare any of your
-  POJO to be "prepared" so that AOP framework knows to start intercepting
-  either method, field, or constructor invocations using the dynamic Aop.
-  </para> <para> For PojoCache, we only allow all the fields (both read and
-  write) to be intercepted. That is, we don't care for the method level
-  interception since it is the state that we are interested in. So you should
-  only need to change your POJO class name. For details of the pointcut
-  language, please refer to JBoss Aop. </para> <para> The standalone
-  <literal>JBoss Cache</literal> distribution package provides an example
-  declaration for the tutorial classes, namely, <literal>Person</literal> and
-  <literal>Address</literal> . Detailed class declaration for
-  <literal>Person</literal> and <literal>Address</literal> are provided in the
-  Appendix section. But here is the snippet for
-  <literal>pojocache-aop.xml</literal> : </para> <programlisting>
-         &lt;aop&gt; &lt;prepare expr="field(*
-         $instanceof{@org.jboss.cache.pojo.annotation.Replicable}-&gt;*)"
-         /&gt; &lt;/aop&gt;
-      </programlisting> and then notice the annotation @Replicable used in the
-  <literal>Person</literal> and <literal>Address</literal> POJOs. Also note
-  that @Replicable is now inheritant. For example, sub-class of
-  <literal>Person</literal> such as <literal>Student</literal> will also be
-  aspectized by JBoss Aop as well. If you want to stop this inheritance
-  behavior, you can simply remove the <literal>$instanceof</literal>
-  declaration in the prepare statement, e.g., <programlisting>
-         &lt;aop&gt; &lt;prepare expr="field(*
-         @org.jboss.cache.pojo.annotation.Replicable-&gt;*)" /&gt;
-         &lt;/aop&gt;
-      </programlisting> <para> Detailed semantics of
-  <literal>pojocache-aop.xml</literal> (or equivalently
-  <literal>pojocache-aop.xml</literal> ) can again be found in JBoss Aop. But
-  above statements basically declare all field read and write operations in
-  classes <code>Address</code> and <code>Person</code> will be "prepared" (or
-  "aspectized"). Note that: </para> <itemizedlist>
-      <listitem>The wildcard at the end of the expression signifies all fields
-      in the POJO</listitem>
+    <orderedlist>
+      <listitem>
+        <para>The <literal>aoppath</literal> option must point to the location
+        of pojocache-aop.xml</para>
+      </listitem>
 
-      <listitem>You can potentially replace specific class name with wildcard
-      that includes all the POJOs inside the same package space</listitem>
+      <listitem>
+        <para>The <literal>src</literal> option must point to the location of
+        your class files that are to be instrumented. This is typically the
+        output folder of a <literal>javac</literal> run.</para>
+      </listitem>
+    </orderedlist>
 
-      <listitem>The <code>instanceof</code> operator declares any sub-type or
-      sub-class of the specific POJO will also be "aspectized". For example,
-      if a <code>Student</code> class is a subclass of <code>Person</code> ,
-      JBossAop will automatically instrument it as well!</listitem>
+    <para>The following is an example ant task which performs compile-time
+    instrumentation:</para>
 
-      <listitem>We intercept the field of all access levels (i.e.,
-      <literal>private</literal> , <literal>protected</literal> ,
-      <literal>public</literal> , etc.) The main reason being that we consider
-      all fields as stateful data. However, we can relax this requirement in
-      the future if there is a use case for it.</listitem>
+    <para><programlisting>&lt;taskdef name="aopc" classname="org.jboss.aop.ant.AopC" classpathref="aop.classpath"/&gt; 
+&lt;target name="aopc" depends="compile" description="Precompile aop class"&gt;
+    &lt;aopc compilerclasspathref="aop.classpath" verbose="true"&gt; 
+       &lt;src path="${build}"/&gt;
+       &lt;include name="org/jboss/cache/aop/test/**/*.class"/&gt;
+       &lt;aoppath path="${output}/resources/pojocache-aop.xml"/&gt;
+       &lt;classpath path="${build}"/&gt; 
+       &lt;classpath refid="lib.classpath"/&gt; 
+    &lt;/aopc&gt; 
+&lt;/target&gt;         </programlisting>In this example, once the aopc target
+    is executeed the clasess in the build directory are modified. They can
+    then be packaged in a jar and loaded using the normal Java
+    mechanisms.</para>
+  </sect1>
 
-      <listitem>We don't intercept field modifiers of <literal>final</literal>
-      and <literal>transient</literal> though. That is, field with these
-      modifiers are not stored in cache and is not replicated either. If you
-      don't want your field to be managed by the cache, you can declare them
-      with these modifiers, e.g., transient.</listitem>
-    </itemizedlist></sect1>
+  <sect1>
+    <title>Understanding the provided AOP descriptor</title>
 
+    <para>The advanced user might decide to alter the provided AOP descritor.
+    In order to do this, it is important to understand the reaons behind what
+    is provided, and what is required by POJO Cache. Previous sections have
+    mentioned that any class with the <literal>@Replicable</literal>
+    annotation will be instrumented. This happens, because the provided AOP
+    descriptor, <literal>pojocache-aop.xml</literal>, has a perpare statement
+    which matches any class (or subclass) using the annotation. This is shown
+    in the following snippet:</para>
+
+    <programlisting>&lt;prepare expr="field(* $instanceof{@org.jboss.cache.pojo.annotation.Replicable}-&gt;*)"/&gt;     </programlisting>
+
+    <para>More specifically, any code which accesses a field on a class which
+    has been annotated with <literal>@Replicable</literal>, will be
+    instrumented: The "field" pointcut in the expression matches both read and
+    write operations. The wildcard "*" indicates that all java protection
+    modes are intercepted (private, package, protected, public). The
+    <literal>$instanceof</literal> expression refers to any annotation that
+    subclasses <literal>@Replicable</literal>. Finally, the ending wildcard
+    allows the matched field to have any name.</para>
+  </sect1>
+
   <sect1>
     <title>Annotation</title>
 
@@ -145,27 +133,51 @@
     declaration since there will be no need for external metadata xml
     descriptor.</para>
 
-    <sect2><title>POJO annotation for instrumentation</title> <para> To
-    support annotation (in order to simplify user's development effort), the
-    JBoss Cache distribution ships with a <literal>pojocache-aop.xml</literal>
-    under the <literal>resources</literal> directory. For reference, here is
-    annotation definition from <literal>pojocache-aop.xml</literal> again :
-    <programlisting>
+    <sect2>
+       
+
+      <title>POJO annotation for instrumentation</title>
+
+       
+
+      <para>To support annotation (in order to simplify user's development
+      effort), the JBoss Cache distribution ships with a
+      <literal>pojocache-aop.xml</literal> under the
+      <literal>resources</literal> directory. For reference, here is
+      annotation definition from <literal>pojocache-aop.xml</literal> again :
+      <programlisting>
                &lt;aop&gt; &lt;prepare expr="field(*
                @org.jboss.cache.pojo.annotation.Replicable-&gt;*)"
                /&gt; &lt;/aop&gt;
             </programlisting> Basically, it simply states that any annotation
-    with both marker interfaces will be "aspectized" accordingly. </para>
-    <para> Here is a code snippet that illustrate the declaration: </para>
-    <programlisting>
+      with both marker interfaces will be "aspectized" accordingly.</para>
+
+       
+
+      <para>Here is a code snippet that illustrate the declaration:</para>
+
+       
+
+      <programlisting>
             @org.jboss.cache.pojo.annotation.Replicable public class
             Person {...}
-         </programlisting> The above declaration will instrument the class
-    <literal>Person</literal> and all of its sub-classes. That is, if
-    <literal>Student</literal> sub-class from <literal>Personal</literal> ,
-    then it will get instrumented automatically without further annotation
-    declaration.</sect2>
+         </programlisting>
 
+       The above declaration will instrument the class 
+
+      <literal>Person</literal>
+
+       and all of its sub-classes. That is, if 
+
+      <literal>Student</literal>
+
+       sub-class from 
+
+      <literal>Personal</literal>
+
+       , then it will get instrumented automatically without further annotation declaration. 
+    </sect2>
+
     <sect2>
       <title>JDK5.0 field level annotations</title>
 

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java	2008-01-16 22:15:37 UTC (rev 5150)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCache.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -241,6 +241,14 @@
     * @param listener the listener to remove
     */
    void removeListener(Object listener);
+   
+   /**
+    * Get's the thread context for all POJO Cache operations.
+    * 
+    * @return the current thread's context
+    * @since 2.1
+    */
+   PojoCacheThreadContext getThreadContext();
 
    /**
     * Obtain the underlying generic cache system. Use this for non-POJO cache operation, e.g.

Copied: pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java (from rev 5149, pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java)
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java	                        (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/PojoCacheThreadContext.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -0,0 +1,50 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., 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.cache.pojo;
+
+
+/**
+ * Represents the thread specific context for POJO Cache operations against a particular cache instance. This is
+ * primarily used to change thread specific options. Once set, they remain for the entire lifetime of the thread.
+ * 
+ * Instances of this class can only be obtained by {@link PojoCache#getThreadContext}
+ * 
+ * @author Jason T. Greene
+ * @since 2.1
+ */
+public interface PojoCacheThreadContext
+{   
+   /**
+    * Returns whether or not this thread should trigger gravitation when a cache-miss occurs. The default is false.
+    * 
+    * @return true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
+    */
+   public boolean isGravitationEnabled();
+   
+   /**
+    * Enables or disables gravitation on cache-miss
+    * 
+    * @param gravitate  true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
+    */
+   public void setGravitationEnabled(boolean gravitate);
+}
\ No newline at end of file

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	2008-01-16 22:15:37 UTC (rev 5150)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/InternalHelper.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -13,6 +13,7 @@
 import org.jboss.cache.Cache;
 import org.jboss.cache.CacheException;
 import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCache;
 import org.jboss.cache.pojo.PojoCacheException;
 import org.jboss.cache.pojo.util.ObjectUtil;
 
@@ -26,11 +27,13 @@
 {
    private static  Log log = LogFactory.getLog(InternalHelper.class.getName());
 
-   private Cache cache;
+   private Cache<Object, Object> cache;
+   private PojoCache pcache;
 
-   InternalHelper(Cache cache)
+   InternalHelper(PojoCache pcache)
    {
-      this.cache = cache;
+      this.cache = pcache.getCache();
+      this.pcache = pcache;
    }
 
    PojoInstance getPojoInstance(Fqn fqn) throws CacheException
@@ -86,7 +89,8 @@
 
    private Object get(Fqn fqn, Object key, boolean gravitate) throws CacheException
    {
-      if (gravitate)
+      // Only gravitate when we have to and only when the user has enabled it
+      if (gravitate && pcache.getThreadContext().isGravitationEnabled())
       {
          cache.getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
          Object obj = cache.get(fqn, key);

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-01-16 22:15:37 UTC (rev 5150)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -58,7 +58,7 @@
    {
       pojoCache = cache;
       this.cache = pojoCache.getCache();
-      internal_ = new InternalHelper(this.cache);
+      internal_ = new InternalHelper(cache);
       graphHandler_ = new ObjectGraphHandler(pojoCache, internal_);
       collectionHandler_ = new CollectionClassHandler(pojoCache, internal_);
       serializableHandler_ = new SerializableObjectHandler(pojoCache, internal_);

Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-01-16 22:15:37 UTC (rev 5150)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -24,6 +24,7 @@
 import org.jboss.cache.factories.XmlConfigurationParser;
 import org.jboss.cache.pojo.PojoCache;
 import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.PojoCacheThreadContext;
 import org.jboss.cache.pojo.annotation.Attach;
 import org.jboss.cache.pojo.annotation.Detach;
 import org.jboss.cache.pojo.annotation.Find;
@@ -44,6 +45,7 @@
    private Map cachedTypes_ = new WeakHashMap();
    private boolean hasCreate_ = false;
    private CacheListenerAdaptor listenerAdaptor = new CacheListenerAdaptor(this);
+   private PojoCacheThreadContext threadContext = new PojoCacheThreadContextImpl();
 
    public PojoCacheImpl(String configStr, boolean toStart)
    {
@@ -319,6 +321,11 @@
             cache.removeCacheListener(listenerAdaptor);
       }
    }
+   
+   public PojoCacheThreadContext getThreadContext()
+   {
+      return threadContext;
+   }
 
    public Cache<Object,Object> getCache()
    {

Copied: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java (from rev 5149, pojo/branches/2.1/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java)
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java	                        (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheThreadContextImpl.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -0,0 +1,46 @@
+package org.jboss.cache.pojo.impl;
+
+import org.jboss.cache.pojo.PojoCacheThreadContext;
+
+public class PojoCacheThreadContextImpl implements PojoCacheThreadContext
+{
+   private static final int GRAVITATE = 0;
+   private static final Boolean GRAVITATE_DEFAULT = false;
+   
+   // Every cache instance gets it's own configuration
+   // An array is used to conserve memory usage since reclamation is slow with TLs, and prevent CL leaks
+   // In the future, if we get multiple booleans, use bitwise operations on an integer 
+   // as the first entry
+   private final ThreadLocal<Object[]> state = new ThreadLocal<Object[]>()
+   {
+      @Override
+      protected Object[] initialValue()
+      {
+         return new Object[] {GRAVITATE_DEFAULT};
+      }
+   };
+   
+   PojoCacheThreadContextImpl() 
+   {
+   }
+
+   /**
+    * Returns whether or not this thread should trigger gravitation when a cache-miss occurs. The default is false.
+    * 
+    * @return true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
+    */
+   public boolean isGravitationEnabled()
+   {
+      return (Boolean) state.get()[GRAVITATE];
+   }
+   
+   /**
+    * Enables or disables gravitation on cache-miss
+    * 
+    * @param gravitate  true if gravitation should be triggered on cache-miss, false if gravitation should not be triggered
+    */
+   public void setGravitationEnabled(boolean gravitate)
+   {
+      state.get()[GRAVITATE] = gravitate;
+   }
+}

Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/BuddyReplicationTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/BuddyReplicationTest.java	2008-01-16 22:15:37 UTC (rev 5150)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/BuddyReplicationTest.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -65,6 +65,10 @@
       addBuddyReplication(cfg2);
       cache1 = PojoCacheFactory.createCache(cfg2, toStart);
       cache1.start();
+      
+      // Enable gravitation
+      cache.getThreadContext().setGravitationEnabled(true);
+      cache1.getThreadContext().setGravitationEnabled(true);
    }
 
    @AfterMethod(alwaysRun = true)

Copied: pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java (from rev 5149, pojo/branches/2.1/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java)
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java	                        (rev 0)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/PojoCacheThreadContextTest.java	2008-01-16 22:17:11 UTC (rev 5151)
@@ -0,0 +1,132 @@
+/*
+ * 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.cache.pojo;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNull;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.buddyreplication.NextMemberBuddyLocatorConfig;
+import org.jboss.cache.config.BuddyReplicationConfig;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.pojo.test.Person;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * A BuddyReplicatedTest.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 4717 $
+ */
+ at Test(groups = {"functional"})
+public class PojoCacheThreadContextTest 
+{
+   Log log = LogFactory.getLog(ReplicatedTest.class);
+   volatile PojoCache cache, cache1;
+
+   @BeforeMethod(alwaysRun = true)
+   protected void setUp() throws Exception
+   {
+      log.info("setUp() ....");
+      boolean toStart = false;
+      Configuration cfg1 = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.LOCAL);
+      cache = PojoCacheFactory.createCache(cfg1, toStart);
+      cache.start();
+      Configuration cfg2 = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.LOCAL);
+      cache1 = PojoCacheFactory.createCache(cfg2, toStart);
+      cache1.start();
+   }
+
+   @AfterMethod(alwaysRun = true)
+   protected void tearDown() throws Exception
+   {
+      cache.stop();
+      cache1.stop();
+   }
+
+   public void testDefault()
+   {
+      assertEquals(cache.getThreadContext().isGravitationEnabled(), false);
+      assertEquals(cache1.getThreadContext().isGravitationEnabled(), false);
+   }
+   
+   private class TestThread extends Thread
+   {
+      public volatile Throwable t;
+
+      @Override
+      public void run()
+      {
+         try
+         {
+            cache1.getThreadContext().setGravitationEnabled(true);
+            assertEquals(cache.getThreadContext().isGravitationEnabled(), false);
+            assertEquals(cache1.getThreadContext().isGravitationEnabled(), true);
+         
+            cache.getThreadContext().setGravitationEnabled(true);
+            assertEquals(cache.getThreadContext().isGravitationEnabled(), true);
+            assertEquals(cache1.getThreadContext().isGravitationEnabled(), true);
+         }
+         catch (Throwable t)
+         {
+            this.t = t;
+         }
+      }
+   };
+
+   public void testThreadIsolation() throws Throwable
+   {
+      assertEquals(cache.getThreadContext().isGravitationEnabled(), false);
+      assertEquals(cache1.getThreadContext().isGravitationEnabled(), false);
+      
+      
+      TestThread t1 = new TestThread();
+      t1.start();
+      t1.join();
+      if (t1.t != null)
+         throw t1.t;
+      
+      assertEquals(cache.getThreadContext().isGravitationEnabled(), false);
+      assertEquals(cache1.getThreadContext().isGravitationEnabled(), false);
+
+      cache1.getThreadContext().setGravitationEnabled(true);
+      assertEquals(cache.getThreadContext().isGravitationEnabled(), false);
+      assertEquals(cache1.getThreadContext().isGravitationEnabled(), true);
+      t1 = new TestThread();
+      t1.start();
+      t1.join();
+      if (t1.t != null)
+         throw t1.t;
+      
+      assertEquals(cache.getThreadContext().isGravitationEnabled(), false);
+      assertEquals(cache1.getThreadContext().isGravitationEnabled(), true);
+   }
+}




More information about the jbosscache-commits mailing list