JBoss Cache SVN: r5414 - pojo/branches/2.1/src/main/resources.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2008-03-11 19:09:58 -0400 (Tue, 11 Mar 2008)
New Revision: 5414
Removed:
pojo/branches/2.1/src/main/resources/replSync-service.xml
Log:
Drop unneeded descriptor
Deleted: pojo/branches/2.1/src/main/resources/replSync-service.xml
===================================================================
--- pojo/branches/2.1/src/main/resources/replSync-service.xml 2008-03-11 21:59:36 UTC (rev 5413)
+++ pojo/branches/2.1/src/main/resources/replSync-service.xml 2008-03-11 23:09:58 UTC (rev 5414)
@@ -1,175 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- ===================================================================== -->
-<!-- -->
-<!-- Sample TreeCache Service Configuration -->
-<!-- -->
-<!-- ===================================================================== -->
-
-<server>
-
- <!-- ==================================================================== -->
- <!-- Defines TreeCache configuration -->
- <!-- ==================================================================== -->
-
- <mbean code="org.jboss.cache.jmx.CacheJmxWrapper"
- name="jboss.cache:service=TreeCache">
-
- <depends>jboss:service=Naming</depends>
- <depends>jboss:service=TransactionManager</depends>
-
- <!--
- Configure the TransactionManager
- -->
- <attribute name="TransactionManagerLookupClass">org.jboss.cache.transaction.GenericTransactionManagerLookup
- </attribute>
-
- <!--
- Isolation level : SERIALIZABLE
- REPEATABLE_READ (default)
- READ_COMMITTED
- READ_UNCOMMITTED
- NONE
- -->
- <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
-
- <!--
- Valid modes are LOCAL
- REPL_ASYNC
- REPL_SYNC
- INVALIDATION_ASYNC
- INVALIDATION_SYNC
- -->
- <attribute name="CacheMode">REPL_SYNC</attribute>
-
- <!--
- Just used for async repl: use a replication queue
- -->
- <attribute name="UseReplQueue">false</attribute>
-
- <!--
- Replication interval for replication queue (in ms)
- -->
- <attribute name="ReplQueueInterval">0</attribute>
-
- <!--
- Max number of elements which trigger replication
- -->
- <attribute name="ReplQueueMaxElements">0</attribute>
-
- <!-- Name of cluster. Needs to be the same for all TreeCache nodes in a
- cluster in order to find each other.
- -->
- <attribute name="ClusterName">JBossCache-Cluster</attribute>
-
- <!--Uncomment next three statements to enable JGroups multiplexer.
-This configuration is dependent on the JGroups multiplexer being
-registered in an MBean server such as JBossAS. -->
- <!--
- <depends>jgroups.mux:name=Multiplexer</depends>
- <attribute name="MultiplexerService">jgroups.mux:name=Multiplexer</attribute>
- <attribute name="MultiplexerStack">fc-fast-minimalthreads</attribute>
- -->
-
- <!-- JGroups protocol stack properties.
- ClusterConfig isn't used if the multiplexer is enabled and successfully initialized.
- -->
- <attribute name="ClusterConfig">
- <config>
- <UDP mcast_addr="228.10.10.10"
- mcast_port="45588"
- tos="8"
- ucast_recv_buf_size="20000000"
- ucast_send_buf_size="640000"
- mcast_recv_buf_size="25000000"
- mcast_send_buf_size="640000"
- loopback="false"
- discard_incompatible_packets="true"
- max_bundle_size="64000"
- max_bundle_timeout="30"
- use_incoming_packet_handler="true"
- ip_ttl="2"
- enable_bundling="false"
- enable_diagnostics="true"
-
- use_concurrent_stack="true"
-
- thread_naming_pattern="pl"
-
- thread_pool.enabled="true"
- thread_pool.min_threads="1"
- thread_pool.max_threads="25"
- thread_pool.keep_alive_time="30000"
- thread_pool.queue_enabled="true"
- thread_pool.queue_max_size="10"
- thread_pool.rejection_policy="Run"
-
- oob_thread_pool.enabled="true"
- oob_thread_pool.min_threads="1"
- oob_thread_pool.max_threads="4"
- oob_thread_pool.keep_alive_time="10000"
- oob_thread_pool.queue_enabled="true"
- oob_thread_pool.queue_max_size="10"
- oob_thread_pool.rejection_policy="Run"/>
-
- <PING timeout="2000" num_initial_members="3"/>
- <MERGE2 max_interval="30000" min_interval="10000"/>
- <FD_SOCK/>
- <FD timeout="10000" max_tries="5" shun="true"/>
- <VERIFY_SUSPECT timeout="1500"/>
- <pbcast.NAKACK max_xmit_size="60000"
- use_mcast_xmit="false" gc_lag="0"
- retransmit_timeout="300,600,1200,2400,4800"
- discard_delivered_msgs="true"/>
- <UNICAST timeout="300,600,1200,2400,3600"/>
- <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
- max_bytes="400000"/>
- <pbcast.GMS print_local_addr="true" join_timeout="5000"
- join_retry_timeout="2000" shun="false"
- view_bundling="true" view_ack_collection_timeout="5000"/>
- <FRAG2 frag_size="60000"/>
- <pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/>
- <!-- <pbcast.STATE_TRANSFER/> -->
- <pbcast.FLUSH timeout="0"/>
- </config>
- </attribute>
-
-
- <!--
- Whether or not to fetch state on joining a cluster
- NOTE this used to be called FetchStateOnStartup and has been renamed to be more descriptive.
- -->
- <attribute name="FetchInMemoryState">true</attribute>
-
- <!--
- The max amount of time (in milliseconds) we wait until the
- state (ie. the contents of the cache) are retrieved from
- existing members in a clustered environment
- -->
- <attribute name="StateRetrievalTimeout">15000</attribute>
-
- <!--
- Number of milliseconds to wait until all responses for a
- synchronous call have been received.
- -->
- <attribute name="SyncReplTimeout">15000</attribute>
-
- <!-- Max number of milliseconds to wait for a lock acquisition -->
- <attribute name="LockAcquisitionTimeout">10000</attribute>
-
- <!--
- Indicate whether to use region based marshalling or not. Set this to true if you are running under a scoped
- class loader, e.g., inside an application server. Default is "false".
- -->
- <attribute name="UseRegionBasedMarshalling">true</attribute>
- </mbean>
-
-
- <!-- Uncomment to get a graphical view of the TreeCache MBean above -->
- <!-- <mbean code="org.jboss.cache.TreeCacheView" name="jboss.cache:service=TreeCacheView">-->
- <!-- <depends>jboss.cache:service=TreeCache</depends>-->
- <!-- <attribute name="CacheService">jboss.cache:service=TreeCache</attribute>-->
- <!-- </mbean>-->
-
-
-</server>
16 years, 10 months
JBoss Cache SVN: r5413 - in core/trunk/src/main/java/org/jboss/cache: interceptors and 1 other directories.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-03-11 17:59:36 -0400 (Tue, 11 Mar 2008)
New Revision: 5413
Modified:
core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
Log:
http://jira.jboss.org/jira/browse/JBCACHE-1278
Modified: core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-03-11 21:38:32 UTC (rev 5412)
+++ core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-03-11 21:59:36 UTC (rev 5413)
@@ -29,6 +29,7 @@
// defaults to true.
private boolean originLocal = true;
private boolean txHasMods;
+ private boolean cacheLoaderHasMods;
private boolean localRollbackOnly;
private MethodCall methodCall;
@@ -200,6 +201,7 @@
", optionOverrides=" + optionOverrides +
", originLocal=" + originLocal +
", txHasMods=" + txHasMods +
+ ", cacheLoaderHasMods=" + cacheLoaderHasMods +
'}';
}
@@ -213,6 +215,19 @@
txHasMods = b;
}
+ /**
+ * Cache loader might have mods which are different from TX's mods; e.g. when cache is local and passivation is on.
+ */
+ public boolean isCacheLoaderHasMods()
+ {
+ return cacheLoaderHasMods;
+ }
+
+ public void setCacheLoaderHasMods(boolean cacheLoaderHasMods)
+ {
+ this.cacheLoaderHasMods = cacheLoaderHasMods;
+ }
+
public boolean isLocalRollbackOnly()
{
return localRollbackOnly;
@@ -256,6 +271,7 @@
this.setOriginLocal(template.isOriginLocal());
this.setTransaction(template.getTransaction());
this.setTxHasMods(template.isTxHasMods());
+ this.setCacheLoaderHasMods(template.isCacheLoaderHasMods());
}
public boolean equals(Object o)
@@ -268,6 +284,7 @@
if (localRollbackOnly != that.localRollbackOnly) return false;
if (originLocal != that.originLocal) return false;
if (txHasMods != that.txHasMods) return false;
+ if (cacheLoaderHasMods!= that.cacheLoaderHasMods) return false;
if (globalTransaction != null ? !globalTransaction.equals(that.globalTransaction) : that.globalTransaction != null)
{
return false;
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java 2008-03-11 21:38:32 UTC (rev 5412)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java 2008-03-11 21:59:36 UTC (rev 5413)
@@ -82,7 +82,7 @@
if (inTransaction())
{
if (trace) log.trace("transactional so don't put stuff in the cloader yet.");
- if (ctx.isTxHasMods())
+ if (ctx.isCacheLoaderHasMods())
{
// this is a commit call.
if (trace) log.trace("Calling loader.commit() for gtx " + gtx);
@@ -130,7 +130,7 @@
if (inTransaction())
{
if (trace) log.trace("transactional so don't put stuff in the cloader yet.");
- if (ctx.isTxHasMods())
+ if (ctx.isCacheLoaderHasMods())
{
// this is a rollback method
if (preparingTxs.containsKey(gtx))
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2008-03-11 21:38:32 UTC (rev 5412)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2008-03-11 21:59:36 UTC (rev 5413)
@@ -205,11 +205,11 @@
private void addToModificationList(GlobalTransaction gtx, MethodCall m, InvocationContext ctx)
{
Option opt = ctx.getOptionOverrides();
-// if (opt == null || !opt.isCacheModeLocal())
-// {
+ if (opt == null || !opt.isCacheModeLocal())
+ {
txTable.addModification(gtx, m);
if (log.isDebugEnabled()) log.debug("Adding Method " + m + " to modification list");
-// }
+ }
if (cache.getCacheLoaderManager() != null) txTable.addCacheLoaderModification(gtx, m);
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-03-11 21:38:32 UTC (rev 5412)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/TxInterceptor.java 2008-03-11 21:59:36 UTC (rev 5413)
@@ -865,10 +865,11 @@
*
* @param gtx
*/
- protected void runCommitPhase(InvocationContext ctx, GlobalTransaction gtx, Transaction tx, List modifications, boolean onePhaseCommit)
+ protected void runCommitPhase(InvocationContext ctx, GlobalTransaction gtx, Transaction tx, List modifications, List clModifications, boolean onePhaseCommit)
{
// set the hasMods flag in the invocation ctx. This should not be replicated, just used locally by the interceptors.
ctx.setTxHasMods(modifications != null && modifications.size() > 0);
+ ctx.setCacheLoaderHasMods(clModifications != null && clModifications.size() > 0);
try
{
MethodCall commitMethod;
@@ -1224,12 +1225,14 @@
log.error("afterCompletion error: " + status, e);
}
+ if (trace) log.trace("calling aftercompletion for " + gtx);
- if (trace) log.trace("calling aftercompletion for " + gtx);
+ List cacheLoaderModifications = null;
// set any transaction wide options as current for this thread.
if (entry != null)
{
modifications = entry.getModifications();
+ cacheLoaderModifications = entry.getCacheLoaderModifications();
ctx.setOptionOverrides(entry.getOption());
}
if (tx != null) transactions.remove(tx);
@@ -1241,7 +1244,7 @@
// if this is optimistic or sync repl
boolean onePhaseCommit = !configuration.isNodeLockingOptimistic() && configuration.getCacheMode() == Configuration.CacheMode.REPL_ASYNC;
if (log.isDebugEnabled()) log.debug("Running commit phase. One phase? " + onePhaseCommit);
- runCommitPhase(ctx, gtx, tx, modifications, onePhaseCommit);
+ runCommitPhase(ctx, gtx, tx, modifications, cacheLoaderModifications, onePhaseCommit);
log.debug("Finished commit phase");
break;
case Status.STATUS_UNKNOWN:
@@ -1337,7 +1340,7 @@
// fetch the modifications before the transaction is committed
// (and thus removed from the txTable)
setTransactionalContext(tx, gtx, ctx);
- if (modifications.size() == 0)
+ if (!entry.existModifications())
{
if (trace) log.trace("No modifications in this tx. Skipping beforeCompletion()");
return;
Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-03-11 21:38:32 UTC (rev 5412)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-03-11 21:59:36 UTC (rev 5413)
@@ -432,4 +432,12 @@
{
this.orderedSynchronizationHandler = orderedSynchronizationHandler;
}
+
+ /**
+ * Returns true if modifications were registered to either modificationList or to class loader modifications list.
+ */
+ public boolean existModifications()
+ {
+ return !modification_list.isEmpty() || !cl_mod_list.isEmpty();
+ }
}
16 years, 10 months
JBoss Cache SVN: r5412 - pojo/branches/2.1.
by jbosscache-commits@lists.jboss.org
Author: galder.zamarreno(a)jboss.com
Date: 2008-03-11 17:38:32 -0400 (Tue, 11 Mar 2008)
New Revision: 5412
Modified:
pojo/branches/2.1/
Log:
Added target folder to svn ignore.
Property changes on: pojo/branches/2.1
___________________________________________________________________
Name: svn:ignore
- .classpath
eclipse-output
output
.project
.settings
+ .classpath
eclipse-output
output
.project
.settings
target
16 years, 10 months
JBoss Cache SVN: r5411 - core/trunk/src/test/java/org/jboss/cache/options.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-03-11 16:36:36 -0400 (Tue, 11 Mar 2008)
New Revision: 5411
Modified:
core/trunk/src/test/java/org/jboss/cache/options/CacheModeLocalSimpleTest.java
Log:
Added test
Modified: core/trunk/src/test/java/org/jboss/cache/options/CacheModeLocalSimpleTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/options/CacheModeLocalSimpleTest.java 2008-03-11 04:05:28 UTC (rev 5410)
+++ core/trunk/src/test/java/org/jboss/cache/options/CacheModeLocalSimpleTest.java 2008-03-11 20:36:36 UTC (rev 5411)
@@ -11,6 +11,7 @@
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Option;
+import org.jboss.cache.misc.TestingUtil;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
import org.testng.annotations.AfterMethod;
@@ -41,9 +42,6 @@
c.setCacheMode("REPL_SYNC");
c.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
- cache1.start();
- cache2.start();
-
cacheModeLocal = new Option();
cacheModeLocal.setCacheModeLocal(true);
}
@@ -51,21 +49,32 @@
@AfterMethod(alwaysRun = true)
public void tearDown()
{
- if (cache1 != null)
- {
- cache1.stop();
- cache1 = null;
- }
+ TestingUtil.killCaches(cache1, cache2);
+ }
- if (cache2 != null)
+ public void testCacheModeLocalWithTx() throws Exception
+ {
+ doTest(false);
+ }
+
+ public void testCacheModeLocalOptimisticWithTx() throws Exception
+ {
+ doTest(true);
+ }
+
+ private void doTest(boolean optimistic) throws Exception
+ {
+ if (optimistic)
{
- cache2.stop();
- cache2 = null;
+ cache1.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.OPTIMISTIC);
+ cache2.getConfiguration().setNodeLockingScheme(Configuration.NodeLockingScheme.OPTIMISTIC);
}
- }
- public void testCacheModeLocalWithTx() throws Exception
- {
+ cache1.start();
+ cache2.start();
+
+ TestingUtil.blockUntilViewsReceived(10000, cache1, cache2);
+
TransactionManager mgr = cache1.getTransactionManager();
mgr.begin();
16 years, 10 months
JBoss Cache SVN: r5410 - in pojo/trunk/src: main/java/org/jboss/cache/pojo/impl and 5 other directories.
by jbosscache-commits@lists.jboss.org
Author: jason.greene(a)jboss.com
Date: 2008-03-11 00:05:28 -0400 (Tue, 11 Mar 2008)
New Revision: 5410
Added:
pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArray.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArrayRegistry.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedPrimitiveArray.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/ArrayInterceptor.java
Modified:
pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CachedType.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.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/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java
pojo/trunk/src/main/java/org/jboss/cache/pojo/util/AopUtil.java
pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml
pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java
pojo/trunk/src/test/java/org/jboss/cache/pojo/ReplicatedByteTest.java
pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java
pojo/trunk/src/test/java/org/jboss/cache/pojo/test/Resource.java
Log:
Add initial support for array interception - PCACHE-13
Cleanup some of the code
Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArray.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArray.java (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArray.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -0,0 +1,124 @@
+/*
+* 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.collection;
+
+import java.lang.reflect.Array;
+
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.impl.CachedType;
+import org.jboss.cache.pojo.impl.PojoCacheImpl;
+
+/**
+ * A CachedArray is the base class for cache backed array access. It replicates the Java array contract.
+ *
+ * @author Jason T. Greene
+ */
+public abstract class CachedArray
+{
+ private static final String LENGTH = "ARRAY.LENGTH";
+ protected PojoCacheImpl cache;
+ protected Fqn<?> fqn;
+ private int length = -1;
+ private Class<?> type;
+
+ public static CachedArray load(Fqn<?> fqn, PojoCacheImpl cache, Class<?> type)
+ {
+ boolean primitive = CachedType.isImmediate(type.getComponentType());
+ CachedArray array = primitive ? new CachedPrimitiveArray(fqn, type, cache) : new CachedObjectArray(fqn, type, cache);
+ return array;
+ }
+
+ public static CachedArray create(Fqn<?> fqn, PojoCacheImpl cache, Object originalArray)
+ {
+ Class<?> type = originalArray.getClass();
+ assert type.isArray();
+
+ Class<?> component = type.getComponentType();
+ boolean primitive = CachedType.isImmediate(component);
+ CachedArray array = primitive ? new CachedPrimitiveArray(fqn, type, cache) : new CachedObjectArray(fqn, type, cache);
+
+ int length = Array.getLength(originalArray);
+ for (int c = 0; c < length; c++)
+ array.set(c, Array.get(originalArray, c));
+
+ array.length = length;
+ array.writeInfo();
+
+ return array;
+ }
+
+ protected CachedArray(Fqn<?> fqn, Class<?> type, PojoCacheImpl cache)
+ {
+ this.fqn = fqn;
+ this.type = type;
+ this.cache = cache;
+ }
+
+ public Fqn<?> getFqn()
+ {
+ return fqn;
+ }
+
+ public abstract void set(int index, Object element);
+
+ public abstract Object get(int index);
+
+ protected void writeInfo()
+ {
+ cache.getCache().put(fqn, LENGTH, length);
+ }
+
+ public void destroy()
+ {
+ cache.getCache().removeNode(fqn);
+ length = 0;
+ }
+
+ public int length()
+ {
+ if (length == -1)
+ {
+ Integer i = (Integer)cache.getCache().get(fqn, LENGTH);
+ length = i != null ? i.intValue() : 0;
+ }
+
+ return length;
+ }
+
+ public Object toArray()
+ {
+ try
+ {
+ int len = length();
+ Object array = Array.newInstance(type.getComponentType(), len);
+ for (int i = 0; i < len; i++)
+ Array.set(array, i, get(i));
+
+ return array;
+ }
+ catch (Exception e)
+ {
+ throw new CacheException("Could not construct array " + type);
+ }
+ }
+}
\ No newline at end of file
Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArrayRegistry.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArrayRegistry.java (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedArrayRegistry.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -0,0 +1,51 @@
+/*
+* 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.collection;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A n internal registry which is responsible for mapping a Java array
+ * instance to a <code>CachedArray</code>.
+ *
+ * @author Jason T. Greene
+ */
+public class CachedArrayRegistry
+{
+ private static ConcurrentMap<Object, CachedArray> map = new ConcurrentHashMap<Object, CachedArray>();
+
+ public static void register(Object array, CachedArray cached)
+ {
+ map.put(array, cached);
+ }
+
+ public static CachedArray unregister(Object array)
+ {
+ return map.remove(array);
+ }
+
+ public static CachedArray lookup(Object array)
+ {
+ return map.get(array);
+ }
+}
Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedObjectArray.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -0,0 +1,64 @@
+/*
+* 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.collection;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.impl.PojoCacheImpl;
+import org.jboss.cache.pojo.util.AopUtil;
+import org.jboss.cache.pojo.util.Null;
+
+/**
+ * A CachedObjectArray is used to back arrays with a component type that extends Object.
+ * It currently maps each array element to a cache Node, to support fine-grained locking.
+ *
+ * @author Jason T. Greene
+ */
+public class CachedObjectArray extends CachedArray
+{
+ protected CachedObjectArray(Fqn<?> fqn, Class<?> type, PojoCacheImpl cache)
+ {
+ super(fqn, type, cache);
+ }
+
+ public void set(int index, Object element)
+ {
+ Fqn<?> fqn = AopUtil.constructFqn(this.fqn, IntegerCache.toString(index));
+
+ cache.attach(fqn, Null.toNullObject(element));
+ }
+
+ public Object get(int index)
+ {
+ Fqn<?> fqn = AopUtil.constructFqn(this.fqn, IntegerCache.toString(index));
+
+ return Null.toNullValue(cache.find(fqn));
+ }
+
+ public void destroy()
+ {
+ // Detach all children to ensure reference cleanup
+ for (int i = 0; i < length(); i++)
+ cache.detach(AopUtil.constructFqn(this.fqn, IntegerCache.toString(i)));
+
+ super.destroy();
+ }
+}
Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedPrimitiveArray.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedPrimitiveArray.java (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/collection/CachedPrimitiveArray.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -0,0 +1,51 @@
+/*
+* 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.collection;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.impl.PojoCacheImpl;
+
+/**
+ * A CachedPrimitiveArray is used to back arrays which have primitive
+ * component types. These are currently mapped to attributes on a single node.
+ *
+ * @author Jason T. Greene
+ */
+public class CachedPrimitiveArray extends CachedArray
+{
+ private static final String ELEMENT = "ARRAY.PELEMENT.";
+
+ protected CachedPrimitiveArray(Fqn<?> fqn, Class<?> type, PojoCacheImpl cache)
+ {
+ super(fqn, type, cache);
+ }
+
+ public void set(int index, Object element)
+ {
+ cache.getCache().put(fqn, ELEMENT + index, element);
+ }
+
+ public Object get(int index)
+ {
+ return cache.getCache().get(fqn, ELEMENT + index);
+ }
+}
\ No newline at end of file
Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AbstractHandler.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -0,0 +1,43 @@
+/*
+* 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.impl;
+
+import org.jboss.cache.Fqn;
+
+abstract class AbstractHandler
+{
+
+ public AbstractHandler()
+ {
+ super();
+ }
+
+ protected abstract boolean handles(Class<?> clazz);
+
+ protected abstract Object remove(Fqn<?> fqn, Fqn<?> referenceingFqn, Object result);
+
+ protected abstract void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj);
+
+ protected abstract Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance);
+
+ protected abstract Fqn<?> getFqn(Object obj);
+}
\ No newline at end of file
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/AdvisedPojoHandler.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -1,10 +1,24 @@
/*
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
+* 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.impl;
import java.lang.reflect.Field;
@@ -22,6 +36,8 @@
import org.jboss.cache.Cache;
import org.jboss.cache.CacheException;
import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCacheException;
+import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
import org.jboss.cache.pojo.interceptors.dynamic.CacheFieldInterceptor;
import org.jboss.cache.pojo.memory.FieldPersistentReference;
import org.jboss.cache.pojo.util.AopUtil;
@@ -35,7 +51,7 @@
* Date: Aug 4, 2005
* @version $Id$
*/
-class AdvisedPojoHandler
+class AdvisedPojoHandler extends AbstractHandler
{
private final Log log = LogFactory.getLog(AdvisedPojoHandler.class);
private Cache<Object, Object> cache_;
@@ -49,8 +65,27 @@
cache_ = pCache_.getCache();
util_ = util;
}
+
+ @Override
+ protected Fqn<?> getFqn(Object obj)
+ {
+ if (obj instanceof Advised)
+ {
+ InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
+ if (advisor == null)
+ throw new PojoCacheException("_putObject(): InstanceAdvisor is null for: " + obj);
+
+ // Step Check for cross references
+ BaseInterceptor interceptor = AopUtil.findCacheInterceptor(advisor);
+ if (interceptor != null)
+ return interceptor.getFqn();
+ }
+
+ return null;
+ }
- public Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance) throws CacheException
+ @Override
+ protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance) throws CacheException
{
CachedType type = pCache_.getCachedType(clazz);
Object obj = Instantiator.newInstance(clazz);
@@ -84,7 +119,8 @@
return obj;
}
- void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
+ @Override
+ protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
{
CachedType type = pCache_.getCachedType(obj.getClass());
// We have a clean slate then.
@@ -168,9 +204,10 @@
}
}
- Object remove(Fqn<?> fqn, Object result, Class<?> clazz) throws CacheException
+ @Override
+ protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object result) throws CacheException
{
- CachedType type = pCache_.getCachedType(clazz);
+ CachedType type = pCache_.getCachedType(result.getClass());
InstanceAdvisor advisor = ((Advised) result)._getInstanceAdvisor();
for (Iterator i = type.getFields().iterator(); i.hasNext();)
{
@@ -196,8 +233,7 @@
}
}
- // batch remove
- cache_.getRoot().getChild(fqn).clearData();
+ cache_.removeNode(fqn);
// Determine if we want to keep the interceptor for later use.
CacheFieldInterceptor interceptor = (CacheFieldInterceptor) AopUtil.findCacheInterceptor(advisor);
// Remember to remove the interceptor from in-memory object but make sure it belongs to me first.
@@ -210,6 +246,12 @@
util_.detachInterceptor(advisor, interceptor);
}
- return null; // Not really null though.
+ return result;
}
+
+ @Override
+ protected boolean handles(Class<?> clazz)
+ {
+ return Advised.class.isAssignableFrom(clazz);
+ }
}
Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ArrayHandler.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -0,0 +1,88 @@
+/*
+* 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.impl;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.collection.CachedArray;
+import org.jboss.cache.pojo.collection.CachedArrayRegistry;
+
+/**
+ * Handles array types.
+ *
+ * @author Jason T. Greene
+ */
+public class ArrayHandler extends AbstractHandler
+{
+ private final PojoCacheImpl cache;
+
+ ArrayHandler(PojoCacheImpl cache)
+ {
+ this.cache = cache;
+ }
+
+ protected Fqn<?> getFqn(Object array)
+ {
+ CachedArray cached = CachedArrayRegistry.lookup(array);
+ return cached != null ? cached.getFqn() : null;
+ }
+
+
+ protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
+ {
+ // Always initialize the ref count so that we can mark this as an AopNode.
+ PojoInstance pojoInstance = InternalHelper.initializeAopInstance(referencingFqn);
+ pojoInstance.set(obj);
+ pojoInstance.setPojoClass(obj.getClass());
+ cache.getCache().put(fqn, PojoInstance.KEY, pojoInstance);
+
+ CachedArray cached = CachedArray.create(fqn, cache, obj);
+ CachedArrayRegistry.register(obj, cached);
+ }
+
+ @Override
+ protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojo)
+ {
+ CachedArray cached = CachedArray.load(fqn, cache, clazz);
+ Object array = cached.toArray();
+ CachedArrayRegistry.register(array, cached);
+
+ return array;
+ }
+
+ @Override
+ protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj)
+ {
+ CachedArray cached = CachedArrayRegistry.unregister(obj);
+ if (cached != null)
+ cached.destroy();
+
+ return obj;
+ }
+
+ @Override
+ protected boolean handles(Class<?> clazz)
+ {
+ return false;
+ //return clazz.isArray();
+ }
+
+}
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CachedType.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CachedType.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CachedType.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -82,7 +82,7 @@
return immediate;
}
- private static boolean isImmediate(Class clazz)
+ public static boolean isImmediate(Class clazz)
{
// Treat enums as a simple type since they serialize to a simple string
return immediates.contains(clazz) || Enum.class.isAssignableFrom(clazz);
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/CollectionClassHandler.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -7,24 +7,23 @@
package org.jboss.cache.pojo.impl;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.proxy.ClassProxy;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.pojo.PojoCacheException;
import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor;
import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
/**
* Handling the Collection class management. Has no consideration of object graph here.
*
@@ -32,7 +31,7 @@
* Date: Aug 4, 2005
* @version $Id$
*/
-class CollectionClassHandler
+class CollectionClassHandler extends AbstractHandler
{
private final Log log = LogFactory.getLog(CollectionClassHandler.class);
private Cache<Object, Object> cache_;
@@ -45,8 +44,17 @@
cache_ = pCache_.getCache();
internal_ = internal;
}
+
+ protected Fqn<?> getFqn(Object collection)
+ {
+ if (! (collection instanceof ClassProxy))
+ return null;
+
+ BaseInterceptor interceptor = CollectionInterceptorUtil.getInterceptor((ClassProxy) collection);
+ return interceptor != null ? interceptor.getFqn() : null;
+ }
- Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance)
+ protected Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance)
throws CacheException
{
Object obj = null;
@@ -76,7 +84,7 @@
return obj;
}
- void put(Fqn fqn, Fqn referencingFqn, Object obj) throws CacheException
+ protected void put(Fqn fqn, Fqn referencingFqn, Object obj) throws CacheException
{
boolean isCollection = false;
@@ -260,17 +268,26 @@
}
}
- Object remove(Fqn fqn, Object obj) throws CacheException
+ @Override
+ protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
{
if (!(obj instanceof ClassProxy))
{
throw new PojoCacheException("CollectionClassHandler.collectionRemoveObject(): object is not a proxy :" + obj);
}
- Interceptor interceptor = CollectionInterceptorUtil.getInterceptor((ClassProxy) obj);
- boolean removeFromCache = true;
+ AbstractCollectionInterceptor interceptor = (AbstractCollectionInterceptor) CollectionInterceptorUtil.getInterceptor((ClassProxy) obj);
// detach the interceptor. This will trigger a copy and remove.
- ((AbstractCollectionInterceptor) interceptor).detach(removeFromCache);
- return ((AbstractCollectionInterceptor) interceptor).getCurrentCopy();
+ interceptor.detach(true);
+ cache_.removeNode(fqn);
+
+ return interceptor.getCurrentCopy();
}
+
+
+ @Override
+ protected boolean handles(Class<?> clazz)
+ {
+ return Collection.class.isAssignableFrom(clazz) || Map.class.isAssignableFrom(clazz);
+ }
}
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/ObjectGraphHandler.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -9,18 +9,9 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.aop.Advised;
-import org.jboss.aop.InstanceAdvisor;
-import org.jboss.aop.advice.Interceptor;
-import org.jboss.aop.proxy.ClassProxy;
-import org.jboss.cache.Cache;
import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.pojo.PojoCacheException;
-import org.jboss.cache.pojo.collection.CollectionInterceptorUtil;
-import org.jboss.cache.pojo.interceptors.dynamic.BaseInterceptor;
-import org.jboss.cache.pojo.util.AopUtil;
/**
* Handle the object graph management.
@@ -29,7 +20,7 @@
* Date: Aug 4, 2005
* @version $Id$
*/
-class ObjectGraphHandler
+class ObjectGraphHandler extends AbstractHandler
{
private PojoCacheImpl cache;
private InternalHelper internal_;
@@ -40,8 +31,19 @@
this.cache = cache;
internal_ = internal;
}
+
+ protected Fqn<?> getFqn(Object obj)
+ {
+ return null;
+ }
+
+ protected boolean handles(Class<?> clazz)
+ {
+ return false;
+ }
- Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance) throws CacheException
+ @Override
+ protected Object get(Fqn<?> fqn, Class<?> clazz, PojoInstance pojoInstance) throws CacheException
{
// Note this is actually the aliasFqn, not the real fqn!
Object obj;
@@ -54,44 +56,13 @@
return obj; // No need to set the instance under fqn. It is located in refFqn anyway.
}
- void put(Fqn fqn, Object obj, String field) throws CacheException
+ @Override
+ protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
{
- CachedType type = cache.getCachedType(obj.getClass());
-
- InstanceAdvisor advisor = null;
- Interceptor interceptor = null;
-
- if (obj instanceof Advised)
- {
- advisor = ((Advised) obj)._getInstanceAdvisor();
- if (advisor == null)
- throw new PojoCacheException("put(): InstanceAdvisor is null for: " + obj);
- // Step Check for cross references
- interceptor = AopUtil.findCacheInterceptor(advisor);
- }
- else
- {
- advisor = ((ClassProxy) obj)._getInstanceAdvisor();
- if (advisor == null)
- throw new PojoCacheException("put(): InstanceAdvisor is null for: " + obj);
- interceptor = CollectionInterceptorUtil.getInterceptor((ClassProxy) obj);
- }
-
- Fqn originalFqn = null;
-
- // ah, found something. So this will be multiple referenced.
- originalFqn = ((BaseInterceptor) interceptor).getFqn();
-
- // This will increment the ref count, reset, and add ref fqn in the current fqn node.
- setupRefCounting(fqn, originalFqn);
- // Store a PojoReference in the external fqn node
- PojoReference pojoReference = new PojoReference();
- pojoReference.setFqn(originalFqn);
- pojoReference.setPojoClass(type.getType());
- internal_.putPojoReference(fqn, pojoReference, field);
+ setupRefCounting(fqn, referencingFqn);
}
- boolean isMultipleReferenced(Fqn internalFqn)
+ boolean isMultipleReferenced(Fqn<?> internalFqn)
{
// Note this is actually the aliasFqn, not the real fqn!
PojoInstance pojoInstance = null;
@@ -108,7 +79,8 @@
}
- void remove(Fqn referencingFqn, Fqn internalFqn, Object pojo)
+ @Override
+ protected Object remove(Fqn<?> fqn, Fqn<?> referencingFqn, Object pojo)
throws CacheException
{
if (log.isDebugEnabled())
@@ -116,22 +88,24 @@
log.debug("remove(): removing object fqn: " + referencingFqn
+ " Will just de-reference it.");
}
- removeFromReference(referencingFqn, internalFqn);
+ removeFromReference(fqn, referencingFqn);
+
+ return null;
}
/**
* Remove the object from the the reference fqn, meaning just decrement the ref counter.
*/
- private void removeFromReference(Fqn referencingFqn, Fqn originalFqn) throws CacheException
+ private void removeFromReference(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
{
- synchronized (referencingFqn)
+ synchronized (originalFqn)
{ // we lock the internal fqn here so no one else has access.
// Decrement ref counting on the internal node
- if (decrementRefCount(referencingFqn, originalFqn) == PojoInstance.INITIAL_COUNTER_VALUE)
+ if (decrementRefCount(originalFqn, referencingFqn) == PojoInstance.INITIAL_COUNTER_VALUE)
{
// No one is referring it so it is safe to remove
// TODO we should make sure the parent nodes are also removed they are empty as well.
- cache.detach(referencingFqn);
+ cache.detach(originalFqn);
}
}
}
@@ -143,26 +117,21 @@
* @param fqn The original fqn node
* @param refFqn The new internal fqn node
*/
- private void setupRefCounting(Fqn fqn, Fqn refFqn) throws CacheException
+ private void setupRefCounting(Fqn<?> fqn, Fqn<?> referencingFqn) throws CacheException
{
- synchronized (refFqn)
- { // we lock the ref fqn here so no one else has access.
+ synchronized (fqn)
+ {
// increment the reference counting
- incrementRefCount(refFqn, fqn);
- // set the internal fqn in fqn so we can reference it.
- if (log.isTraceEnabled())
- {
- log.trace("setupRefCounting(): current fqn: " + fqn + " set to point to: " + refFqn);
- }
+ incrementRefCount(fqn, referencingFqn);
}
}
- private int incrementRefCount(Fqn originalFqn, Fqn referencingFqn) throws CacheException
+ private int incrementRefCount(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
{
return internal_.incrementRefCount(originalFqn, referencingFqn);
}
- private int decrementRefCount(Fqn referencingFqn, Fqn originalFqn) throws CacheException
+ private int decrementRefCount(Fqn<?> originalFqn, Fqn<?> referencingFqn) throws CacheException
{
int count = 0;
if ((count = internal_.decrementRefCount(originalFqn, referencingFqn)) == (PojoInstance.INITIAL_COUNTER_VALUE + 1))
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-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheDelegate.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -48,6 +48,7 @@
private AdvisedPojoHandler advisedHandler_;
private ObjectGraphHandler graphHandler_;
private CollectionClassHandler collectionHandler_;
+ private ArrayHandler arrayHandler;
private SerializableObjectHandler serializableHandler_;
// Use ThreadLocal to hold a boolean isBulkRemove
private ThreadLocal<Boolean> bulkRemove_ = new ThreadLocal<Boolean>();
@@ -63,6 +64,7 @@
collectionHandler_ = new CollectionClassHandler(pojoCache, internal_);
serializableHandler_ = new SerializableObjectHandler(pojoCache, internal_);
advisedHandler_ = new AdvisedPojoHandler(pojoCache, internal_, util_);
+ arrayHandler = new ArrayHandler(pojoCache);
}
public void setBulkRemove(boolean bulk)
@@ -107,29 +109,14 @@
}
}
- public Object putObjectI(Fqn fqn, Object obj, String field) throws CacheException
- {
- // Skip some un-necessary update if obj is the same class as the old one
- Object oldValue = internal_.getPojo(fqn, field);
- if (oldValue == obj && (obj instanceof Advised || obj instanceof ClassProxy))
- {
- if (log.isDebugEnabled())
- {
- log.debug("putObject(): id: " + fqn + " pojo is already in the cache. Return right away.");
- }
- return obj;
- }
- return null;
- }
-
/**
* Note that caller of this method will take care of synchronization within the <code>fqn</code> sub-tree.
*/
- public Object putObjectII(Fqn fqn, Object obj, String field) throws CacheException
+ public Object putObject(Fqn fqn, Object obj, String field) throws CacheException
{
// Skip some un-necessary update if obj is the same class as the old one
Object oldValue = internal_.getPojo(fqn, field);
- if (oldValue == obj)
+ if (oldValue == obj && skipDuplicateAttach(obj))
{
if (log.isDebugEnabled())
{
@@ -143,59 +130,63 @@
pojoCache.detach(fqn, field);
if (obj == null)
- {
return oldValue;// we are done
- }
- // creates the internal node first without going thru the interceptor.
- // This way we don't block on __JBossInternal__ node.
- //createChildNodeFirstWithoutLocking(internalFqn);
-
- if ((obj instanceof Advised || obj instanceof ClassProxy) && isMultipleReferencedPut(obj))
+ AbstractHandler handler = getHandler(obj.getClass());
+ Fqn<?> internalFqn = handler.getFqn(obj);
+
+ if (internalFqn != null)
{
- // we pass in the originating fqn intentionaly
- graphHandler_.put(fqn, obj, field);
+ graphHandler_.put(internalFqn, fqn, obj);
}
else
{
- Fqn internalFqn = createInternalFqn(fqn, obj);
- if (log.isDebugEnabled())
- {
- log.debug("putObject(): id: " + fqn + " will store the pojo in the internal area: "
- + internalFqn);
- }
+ internalFqn = createInternalFqn(fqn, obj);
+ if (log.isDebugEnabled())
+ log.debug("attach(): id: " + fqn + " will store the pojo in the internal area: " + internalFqn);
+
+ handler.put(internalFqn, fqn, obj);
- if (obj instanceof Advised)
- {
- advisedHandler_.put(internalFqn, fqn, obj);
- }
- else if (isCollection(obj))
- {
- collectionHandler_.put(internalFqn, fqn, obj);
- //
- }
- else
- {
- // must be Serializable, including primitive types
- serializableHandler_.put(internalFqn, obj);
- }
-
// Used by notification sub-system
cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "ATTACHED");
-
- setPojoReference(fqn, obj, field, internalFqn);
}
+
+ setPojoReference(fqn, obj, field, internalFqn);
return oldValue;
}
+
+ private boolean skipDuplicateAttach(Object obj)
+ {
+ return obj == null || getHandler(obj.getClass()) != serializableHandler_;
+ }
+
+ private AbstractHandler getHandler(Class<?> clazz)
+ {
+ if (advisedHandler_.handles(clazz))
+ return advisedHandler_;
+
+ if (collectionHandler_.handles(clazz))
+ return collectionHandler_;
+
+ if (arrayHandler.handles(clazz))
+ return arrayHandler;
+
+ if (serializableHandler_.handles(clazz))
+ return serializableHandler_;
+
+ throw new CacheException("Can not manage object. It must be either instrumented, a collection, an array, or Serializable: "
+ + clazz.getName());
+ }
+
- Fqn createInternalFqn(Fqn fqn, Object obj) throws CacheException
+ private Fqn createInternalFqn(Fqn fqn, Object obj) throws CacheException
{
// Create an internal Fqn name
return AopUtil.createInternalFqn(fqn, cache);
}
- Fqn setPojoReference(Fqn fqn, Object obj, String field, Fqn internalFqn) throws CacheException
+ private Fqn setPojoReference(Fqn fqn, Object obj, String field, Fqn internalFqn) throws CacheException
{
// Create PojoReference
CachedType type = pojoCache.getCachedType(obj.getClass());
@@ -249,8 +240,7 @@
return null;
}
- Class clazz = pojoReference.getPojoClass();
- Fqn internalFqn = pojoReference.getFqn();
+ Fqn<?> internalFqn = pojoReference.getFqn();
if (log.isDebugEnabled())
{
@@ -260,37 +250,20 @@
Object result = pojoCache.getObject(internalFqn);
if (result == null)
- {
return null;
- }
if (graphHandler_.isMultipleReferenced(internalFqn))
{
- graphHandler_.remove(fqn, internalFqn, result);
+ graphHandler_.remove(internalFqn, fqn, result);
}
else
{
cache.put(internalFqn, InternalConstant.POJOCACHE_STATUS, "DETACHING");
- if (Advised.class.isAssignableFrom(clazz))
- {
- advisedHandler_.remove(internalFqn, result, clazz);
- internal_.cleanUp(internalFqn, null);
- }
- else if (isCollectionGet(clazz))
- {
- // We need to return the original reference
- result = collectionHandler_.remove(internalFqn, result);
- internal_.cleanUp(internalFqn, null);
- }
- else
- {// Just Serializable objects. Do a brute force remove is ok.
- serializableHandler_.remove();
- internal_.cleanUp(internalFqn, null);
- }
+
+ result = getHandler(result.getClass()).remove(internalFqn, fqn, result);
}
internal_.cleanUp(fqn, field);
- // remove the interceptor as well.
return result;
}
@@ -314,9 +287,9 @@
return map;
}
- private Object getObjectInternal(Fqn fqn, String field) throws CacheException
+ private Object getObjectInternal(Fqn<?> fqn, String field) throws CacheException
{
- Fqn internalFqn = fqn;
+ Fqn<?> internalFqn = fqn;
PojoReference pojoReference = internal_.getPojoReference(fqn, field);
if (pojoReference != null)
{
@@ -341,115 +314,13 @@
return null;
//throw new PojoCacheException("PojoCacheDelegate.getObjectInternal(): null PojoInstance for fqn: " + internalFqn);
- Class clazz = pojoInstance.getPojoClass();
+ Class<?> clazz = pojoInstance.getPojoClass();
+ obj = getHandler(clazz).get(internalFqn, clazz, pojoInstance);
- // Check for both Advised and Collection classes for object graph.
- // Note: no need to worry about multiple referencing here. If there is a graph, we won't come this far.
- if (Advised.class.isAssignableFrom(clazz))
- {
- obj = advisedHandler_.get(internalFqn, clazz, pojoInstance);
- }
- else if (isCollectionGet(clazz))
- {// Must be Collection classes. We will use aop.ClassProxy instance instead.
- obj = collectionHandler_.get(internalFqn, clazz, pojoInstance);
- }
- else
- {
- // Maybe it is just a serialized object.
- obj = serializableHandler_.get(internalFqn, clazz, pojoInstance);
- }
-
InternalHelper.setPojo(pojoInstance, obj);
return obj;
}
- private boolean isCollectionGet(Class clazz)
- {
- if (Map.class.isAssignableFrom(clazz) || Collection.class.isAssignableFrom(clazz))
- {
- return true;
- }
-
- return false;
- }
-
-
- private boolean isMultipleReferencedPut(Object obj)
- {
- Interceptor interceptor = null;
- if (obj instanceof Advised)
- {
- InstanceAdvisor advisor = ((Advised) obj)._getInstanceAdvisor();
- if (advisor == null)
- {
- throw new PojoCacheException("_putObject(): InstanceAdvisor is null for: " + obj);
- }
-
- // Step Check for cross references
- interceptor = AopUtil.findCacheInterceptor(advisor);
- }
- else
- {
- interceptor = CollectionInterceptorUtil.getInterceptor((ClassProxy) obj);
- }
- if (interceptor == null) return false;
-
- Fqn originalFqn = null;
-
- // ah, found something. So this will be multiple referenced.
- originalFqn = ((BaseInterceptor) interceptor).getFqn();
-
- return originalFqn != null;
-
- }
-
- private boolean isCollection(Object obj)
- {
- return obj instanceof Collection || obj instanceof Map;
-
- }
-
- private void detachInterceptor(InstanceAdvisor advisor, Interceptor interceptor,
- boolean detachOnly, Map undoMap)
- {
- if (!detachOnly)
- {
- util_.detachInterceptor(advisor, interceptor);
- undoMap.put(advisor, interceptor);
- }
- else
- {
- undoMap.put(DETACH, interceptor);
- }
- }
-
- private static void undoInterceptorDetach(Map undoMap)
- {
- for (Iterator it = undoMap.keySet().iterator(); it.hasNext();)
- {
- Object obj = it.next();
-
- if (obj instanceof InstanceAdvisor)
- {
- InstanceAdvisor advisor = (InstanceAdvisor) obj;
- BaseInterceptor interceptor = (BaseInterceptor) undoMap.get(advisor);
-
- if (interceptor == null)
- {
- throw new IllegalStateException("PojoCacheDelegate.undoInterceptorDetach(): null interceptor");
- }
-
- advisor.appendInterceptor(interceptor);
- }
- else
- {
- BaseInterceptor interceptor = (BaseInterceptor) undoMap.get(obj);
- boolean copyToCache = false;
- ((AbstractCollectionInterceptor) interceptor).attach(null, copyToCache);
- }
- }
- }
-
private void findChildObjects(Fqn fqn, Map map) throws CacheException
{
// We need to traverse then
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-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/PojoCacheImpl.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -125,17 +125,9 @@
/**
* This public API is called from internal package only.
*/
- public Object putObject(Fqn<?> id, Object pojo, String field)
- throws CacheException
+ public Object putObject(Fqn<?> id, Object pojo, String field) throws CacheException
{
- Object obj = null;
-
- // Maybe this is the same instance already.
- obj = delegate_.putObjectI(id, pojo, field);
- if (obj != null) return obj;
-
- obj = delegate_.putObjectII(id, pojo, field);
- return obj;
+ return delegate_.putObject(id, pojo, field);
}
public Object detach(String id) throws PojoCacheException
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/impl/SerializableObjectHandler.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -7,6 +7,7 @@
package org.jboss.cache.pojo.impl;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@@ -23,7 +24,7 @@
* @author Ben Wang
* @version $Id$
*/
-class SerializableObjectHandler
+class SerializableObjectHandler extends AbstractHandler
{
private Cache<Object, Object> cache;
private PojoCacheImpl pojoCache;
@@ -36,17 +37,29 @@
this.cache = pojoCache.getCache();
internal_ = internal;
}
+
+ protected Fqn<?> getFqn(Object obj)
+ {
+ // Not supported
+ return null;
+ }
+
+ @Override
+ protected boolean handles(Class<?> clazz)
+ {
+ return Serializable.class.isAssignableFrom(clazz);
+ }
- Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance)
- throws CacheException
+ @Override
+ protected Object get(Fqn fqn, Class clazz, PojoInstance pojoInstance) throws CacheException
{
Object obj = internal_.get(fqn, InternalConstant.SERIALIZED);
return obj;
}
- boolean put(Fqn fqn, Object obj)
- throws CacheException
+ @Override
+ protected void put(Fqn<?> fqn, Fqn<?> referencingFqn, Object obj) throws CacheException
{
// Note that JBoss Serialization can serialize any type now.
if (log_.isDebugEnabled())
@@ -56,7 +69,6 @@
}
putIntoCache(fqn, obj);
- return true;
}
private void putIntoCache(Fqn fqn, Object obj)
@@ -74,10 +86,10 @@
internal_.put(fqn, map);
}
- @SuppressWarnings({"CanBeStatic"})
- void remove()
+ @Override
+ protected Object remove(Fqn<?> fqn, Fqn<?> referenceingFqn, Object result) throws CacheException
{
- // No need to do anything here since we will do clean up afterwards.
+ cache.removeNode(fqn);
+ return result;
}
-
-}
+}
\ No newline at end of file
Added: pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/ArrayInterceptor.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/ArrayInterceptor.java (rev 0)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/ArrayInterceptor.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -0,0 +1,86 @@
+/*
+* 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.interceptors.dynamic;
+
+import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.array.ArrayElementReadInvocation;
+import org.jboss.aop.array.ArrayElementWriteInvocation;
+import org.jboss.aop.array.ArrayRegistry;
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.cache.pojo.collection.CachedArray;
+import org.jboss.cache.pojo.collection.CachedArrayRegistry;
+
+/**
+ * AOP interceptor which delegates to POJO Cache
+ *
+ * @author Jason T. Greene
+ */
+public class ArrayInterceptor implements Interceptor
+{
+
+ /* (non-Javadoc)
+ * @see org.jboss.aop.advice.Interceptor#getName()
+ */
+ public String getName()
+ {
+ // TODO Auto-generated method stub
+ return this.getClass().getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.jboss.aop.advice.Interceptor#invoke(org.jboss.aop.joinpoint.Invocation)
+ */
+ public Object invoke(Invocation invocation) throws Throwable
+ {
+ if (invocation instanceof ArrayElementReadInvocation)
+ {
+ ArrayElementReadInvocation read = (ArrayElementReadInvocation)invocation;
+ Object array = read.getTargetObject();
+ CachedArray cached = CachedArrayRegistry.lookup(array);
+ if (cached != null)
+ {
+ int index = read.getIndex();
+ Object element = cached.get(index);
+
+ // AOP only registers on write, work around for now
+ if (element != null && element.getClass().isArray())
+ ArrayRegistry.getInstance().addElementReference(array, index, element);
+
+ return element;
+ }
+ }
+ else if (invocation instanceof ArrayElementWriteInvocation)
+ {
+ ArrayElementWriteInvocation write = (ArrayElementWriteInvocation) invocation;
+ Object array = write.getTargetObject();
+ CachedArray cached = CachedArrayRegistry.lookup(array);
+ if (cached != null)
+ {
+ cached.set(write.getIndex(), write.getValue());
+ return null;
+ }
+ }
+
+ return invocation.invokeNext();
+ }
+
+}
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/interceptors/dynamic/CacheFieldInterceptor.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -12,6 +12,7 @@
import org.apache.commons.logging.LogFactory;
import org.jboss.aop.Advisor;
import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.array.ArrayRegistry;
import org.jboss.aop.joinpoint.FieldInvocation;
import org.jboss.aop.joinpoint.FieldReadInvocation;
import org.jboss.aop.joinpoint.FieldWriteInvocation;
@@ -20,6 +21,8 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.pojo.PojoCacheAlreadyDetachedException;
+import org.jboss.cache.pojo.collection.CachedArray;
+import org.jboss.cache.pojo.collection.CachedArrayRegistry;
import org.jboss.cache.pojo.impl.CachedType;
import org.jboss.cache.pojo.impl.PojoCacheImpl;
import org.jboss.cache.pojo.impl.PojoInstance;
@@ -93,10 +96,10 @@
// Kind of ad hoc now. MethodInvocation should not invoke this.
if (invocation instanceof MethodInvocation)
return invocation.invokeNext();
-
-
+
if (invocation instanceof FieldWriteInvocation)
{
+ Object target = invocation.getTargetObject();
FieldInvocation fieldInvocation =
(FieldInvocation) invocation;
@@ -107,7 +110,7 @@
log_.trace("invoke(): field write interception for fqn: " + fqn_ + " and field: " + field);
}
- verifyAttached(invocation.getTargetObject());
+ verifyAttached(target);
// Only if this field is replicatable. static, transient and final are not.
CachedType fieldType = pCache_.getCachedType(field.getType());
@@ -124,11 +127,11 @@
}
}
- Object obj = fieldInvocation.getTargetObject();
- util_.inMemorySubstitution(obj, field, value);
+ util_.inMemorySubstitution(target, field, value);
}
else if (invocation instanceof FieldReadInvocation)
{
+ Object target = invocation.getTargetObject();
FieldInvocation fieldInvocation =
(FieldInvocation) invocation;
Field field = fieldInvocation.getField();
@@ -146,14 +149,18 @@
else
{
result = pCache_.getObject(fqn_, field.getName());
+
+ // Work around AOP issue with field reads
+ if (result != null && result.getClass().isArray())
+ registerArrayWithAOP(target, field.getName(), result);
}
// If the result is null, the object might have been detached
if (result == null)
- verifyAttached(invocation.getTargetObject());
+ verifyAttached(target);
// Update last known state associated with this pojo.
- util_.inMemorySubstitution(invocation.getTargetObject(), field, result);
+ util_.inMemorySubstitution(target, field, result);
// Allow interceptor chain to process, but ignore the result
invocation.invokeNext();
@@ -165,6 +172,13 @@
return invocation.invokeNext();
}
+ private void registerArrayWithAOP(Object owner, String fieldName, Object array)
+ {
+ CachedArray cached = CachedArrayRegistry.lookup(array);
+ if (cached != null)
+ ArrayRegistry.getInstance().addFieldReference(owner, fieldName, array);
+ }
+
/**
* Check if the pojo is detached already.
*/
Modified: pojo/trunk/src/main/java/org/jboss/cache/pojo/util/AopUtil.java
===================================================================
--- pojo/trunk/src/main/java/org/jboss/cache/pojo/util/AopUtil.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/java/org/jboss/cache/pojo/util/AopUtil.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -67,7 +67,7 @@
* @param advisor
* @return Interceptor
*/
- static public Interceptor findCacheInterceptor(InstanceAdvisor advisor)
+ static public CacheFieldInterceptor findCacheInterceptor(InstanceAdvisor advisor)
{
// TODO we assume there is only one interceptor now.
Interceptor[] interceptors = advisor.getInterceptors();
@@ -77,7 +77,7 @@
Interceptor interceptor = interceptors[i];
if (interceptor instanceof CacheFieldInterceptor)
{
- return interceptor;
+ return (CacheFieldInterceptor)interceptor;
}
}
return null;
Modified: pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml
===================================================================
--- pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/main/resources/META-INF/pojocache-aop.xml 2008-03-11 04:05:28 UTC (rev 5410)
@@ -145,5 +145,13 @@
<prepare expr="field(* $instanceof{(a)org.jboss.cache.pojo.annotation.Replicable}->*)" />
<!-- Work around that ensures annotated classes which do not access fields are instrumented -->
- <introduction expr="class($instanceof{(a)org.jboss.cache.pojo.annotation.Replicable})"/>
-</aop>
\ No newline at end of file
+ <introduction expr="class($instanceof{(a)org.jboss.cache.pojo.annotation.Replicable})"/>
+
+ <!-- Array support
+ <arrayreplacement expr="class($instanceof{(a)org.jboss.cache.pojo.annotation.Replicable})"/>
+ <interceptor name="array" class="org.jboss.cache.pojo.interceptors.dynamic.ArrayInterceptor"/>
+ <arraybind type="READ_WRITE">
+ <interceptor-ref name="array"/>
+ </arraybind>
+ -->
+</aop>
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/ArrayTest.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -8,10 +8,25 @@
package org.jboss.cache.pojo;
+import java.util.HashMap;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.config.Configuration.CacheMode;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeActivated;
+import org.jboss.cache.notifications.annotation.NodeCreated;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.NodePassivated;
+import org.jboss.cache.notifications.annotation.NodeRemoved;
+import org.jboss.cache.notifications.annotation.NodeVisited;
+import org.jboss.cache.notifications.event.NodeEvent;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodeVisitedEvent;
import org.jboss.cache.pojo.test.ArrayObject;
-import org.jboss.cache.pojo.test.Person;
+import org.jboss.cache.pojo.test.ArrayObject.Person;
+import org.testng.AssertJUnit;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -25,22 +40,26 @@
public class ArrayTest
{
Log log = LogFactory.getLog(ArrayTest.class);
- PojoCache cache_;
+ PojoCache cache1, cache2;
@BeforeMethod(alwaysRun = true)
protected void setUp() throws Exception
{
log.info("setUp() ....");
- String configFile = "META-INF/local-service.xml";
- boolean toStart = false;
- cache_ = PojoCacheFactory.createCache(configFile, toStart);
- cache_.start();
+ cache1 = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
+ cache1.getCache().addCacheListener(new MyCacheListener(false));
+ cache1.start();
+
+ cache2 = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), false);
+ cache2.getCache().addCacheListener(new MyCacheListener(true));
+ cache2.start();
+
}
@AfterMethod(alwaysRun = true)
protected void tearDown() throws Exception
{
- cache_.stop();
+ cache1.stop();
}
public void testSimple() throws Exception
@@ -57,14 +76,61 @@
ao.setPerson(0, joe);
- cache_.attach("ao", ao);
+ cache1.attach("/ao", ao);
- // TODO This should trigger a write on team but instead it does a read only. Why?
ao.setPerson(1, ben);
+ ao.setPerson(2, joe);
+ ao.setPerson(3, ben);
+ ao.setPerson(4, joe);
+ ao.setPerson(5, ben);
+
+ AssertJUnit.assertSame(ao.getPerson(1), ben);
+ AssertJUnit.assertSame(ao.getPerson(2), joe);
+ AssertJUnit.assertSame(ao.getPerson(3), ben);
+ AssertJUnit.assertSame(ao.getPerson(4), joe);
+ AssertJUnit.assertSame(ao.getPerson(5), ben);
+
+ ArrayObject obj = (ArrayObject) cache2.find("/ao");
+ Person person = obj.getPerson(4);
+ obj.setPerson(5, person);
+ AssertJUnit.assertSame(ao.getPerson(5), ao.getPerson(4));
+
+ ao.setNum(5, 4);
+ AssertJUnit.assertEquals(4, obj.getNum(5));
+ }
+ @CacheListener
+ public class MyCacheListener
+ {
+ private boolean visits;
+
+ public MyCacheListener(boolean visits)
+ {
+ this.visits = visits;
+ }
+
+ @NodeActivated
+ @NodePassivated
+ @NodeCreated
+ @NodeRemoved
+ @NodeVisited
+ public void print(NodeEvent ne)
+ {
+ if (visits != ne instanceof NodeVisitedEvent)
+ return;
+
+ if (!ne.isPre())
+ System.out.println((!visits ? "[one] " : "[two] ") + ne.getType() + " " + ne.getFqn());
+ }
+
+ @NodeModified
+ public void print(NodeModifiedEvent ne)
+ {
+ if (!visits && !ne.isPre())
+ System.out.println((!visits ? "[one] " : "[two] ") + ne.getType() + " " + ne.getFqn() + " - " + new HashMap(ne.getData()));
+ }
}
-
}
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/ReplicatedByteTest.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/ReplicatedByteTest.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/ReplicatedByteTest.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -80,13 +80,12 @@
Resource res1 = (Resource) cache1.find("resource");
assertEquals("Name ", res.getName(), res1.getName());
- assertEquals("byte ", res.getByte()[0], res1.getByte()[0]);
+ assertEquals("byte ", res.getByte(0), res1.getByte(0));
// field modification
by = 2;
- b[0] = by;
- res1.setByte(b);
+ res.setByte(0, by);
assertEquals("Name ", res.getName(), res1.getName());
- assertEquals("byte ", res.getByte()[0], res1.getByte()[0]);
+ assertEquals("byte ", res.getByte(0), res1.getByte(0));
}
}
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/test/ArrayObject.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -7,17 +7,46 @@
package org.jboss.cache.pojo.test;
+import java.io.Serializable;
+
/**
*/
// We are using JDK1.5 annotation.
@org.jboss.cache.pojo.annotation.Replicable
public class ArrayObject
{
+ // Support array interception and serializable
+ @org.jboss.cache.pojo.annotation.Replicable
+ public static class Person implements Serializable
+ {
+ private static final long serialVersionUID = 1L;
+ private String name;
+ private int age;
+
+ public String getName()
+ {
+ return name;
+ }
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+ public int getAge()
+ {
+ return age;
+ }
+ public void setAge(int age)
+ {
+ this.age = age;
+ }
+ }
private Person[] team;
+ private int[] nums;
public ArrayObject()
{
team = new Person[10];
+ nums = new int[] {1,2,3,4,5,6,7,8,9};
}
public Person[] getTeam()
@@ -29,14 +58,35 @@
{
team = t;
}
+
+ public void setNum(int index, int value)
+ {
+ int nums[] = this.nums;
+ nums[index] = value;
+
+ // This will be optimized away if array interception is enabled
+ this.nums = nums;
+ }
+
+ public int getNum(int index)
+ {
+ return nums[index];
+ }
public Person getPerson(int index)
{
- return team[index];
+ Object o = team[index];
+ return (Person)o;
}
public void setPerson(int index, Person p)
{
- team[index] = p;
+ Person[] array = team;
+ array[index] = p;
+
+ // This will be optimized away if array interception is enabled
+ team = array;
}
}
+
+
Modified: pojo/trunk/src/test/java/org/jboss/cache/pojo/test/Resource.java
===================================================================
--- pojo/trunk/src/test/java/org/jboss/cache/pojo/test/Resource.java 2008-03-11 01:48:44 UTC (rev 5409)
+++ pojo/trunk/src/test/java/org/jboss/cache/pojo/test/Resource.java 2008-03-11 04:05:28 UTC (rev 5410)
@@ -52,6 +52,21 @@
{
bin = b;
}
+
+ public void setByte(int index, byte b)
+ {
+ byte[] array = bin;
+ array[index] = b;
+
+ // This will be optimized away if array interception is enabled
+ // However, it is needed if it is disabled (since serialization is used then)
+ bin = array;
+ }
+
+ public byte getByte(int index)
+ {
+ return bin[index];
+ }
public String toString()
{
16 years, 10 months
JBoss Cache SVN: r5409 - in core/trunk/src: test/java/org/jboss/cache/optimistic and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: mircea.markus
Date: 2008-03-10 21:48:44 -0400 (Mon, 10 Mar 2008)
New Revision: 5409
Modified:
core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticWithCacheLoaderTest.java
Log:
http://jira.jboss.org/jira/browse/JBCACHE-1278
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2008-03-09 22:11:12 UTC (rev 5408)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2008-03-11 01:48:44 UTC (rev 5409)
@@ -205,11 +205,11 @@
private void addToModificationList(GlobalTransaction gtx, MethodCall m, InvocationContext ctx)
{
Option opt = ctx.getOptionOverrides();
- if (opt == null || !opt.isCacheModeLocal())
- {
+// if (opt == null || !opt.isCacheModeLocal())
+// {
txTable.addModification(gtx, m);
if (log.isDebugEnabled()) log.debug("Adding Method " + m + " to modification list");
- }
+// }
if (cache.getCacheLoaderManager() != null) txTable.addCacheLoaderModification(gtx, m);
}
Modified: core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticWithCacheLoaderTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticWithCacheLoaderTest.java 2008-03-09 22:11:12 UTC (rev 5408)
+++ core/trunk/src/test/java/org/jboss/cache/optimistic/OptimisticWithCacheLoaderTest.java 2008-03-11 01:48:44 UTC (rev 5409)
@@ -7,6 +7,7 @@
package org.jboss.cache.optimistic;
import org.jboss.cache.CacheSPI;
+import org.jboss.cache.config.Option;
import org.jboss.cache.loader.CacheLoader;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.Test;
@@ -156,6 +157,22 @@
loader.remove(fqn);
}
+ public void testCacheStoringImplicitTxOptionOverride() throws Exception
+ {
+ CacheSPI<Object, Object> cache = createCacheWithLoader();
+ CacheLoader loader = cache.getCacheLoaderManager().getCacheLoader();
+ Option option = new Option();
+ option.setCacheModeLocal(true);
+ cache.getInvocationContext().setOptionOverrides(option);
+ cache.put(fqn, key, value);
+ assertEquals(value, cache.get(fqn, key));
+ //now lets see if the state has been persisted in the cache loader
+ assertNotNull(loader.get(fqn));
+ assertNotNull(value, loader.get(fqn).get(key));
+ cache.removeNode(fqn);
+ }
+
+
public void testCacheLoading() throws Exception
{
CacheSPI<Object, Object> cache = createCacheWithLoader();
16 years, 10 months
JBoss Cache SVN: r5408 - in core/tags/2.1.0.GA: src/main/java/org/jboss/cache and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-03-09 18:11:12 -0400 (Sun, 09 Mar 2008)
New Revision: 5408
Modified:
core/tags/2.1.0.GA/pom.xml
core/tags/2.1.0.GA/src/main/java/org/jboss/cache/Version.java
Log:
Preparing for release
Modified: core/tags/2.1.0.GA/pom.xml
===================================================================
--- core/tags/2.1.0.GA/pom.xml 2008-03-09 22:07:49 UTC (rev 5407)
+++ core/tags/2.1.0.GA/pom.xml 2008-03-09 22:11:12 UTC (rev 5408)
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
- <jbosscache-core-version>2.1.0-SNAPSHOT</jbosscache-core-version>
+ <jbosscache-core-version>2.1.0.GA</jbosscache-core-version>
</properties>
<parent>
<groupId>org.jboss.cache</groupId>
@@ -336,7 +336,7 @@
<activeByDefault>false</activeByDefault>
</activation>
<properties>
- <jbosscache-core-version>2.1.0-SNAPSHOT-JBossAS</jbosscache-core-version>
+ <jbosscache-core-version>2.1.0.GA-JBossAS</jbosscache-core-version>
</properties>
<dependencies>
<dependency>
Modified: core/tags/2.1.0.GA/src/main/java/org/jboss/cache/Version.java
===================================================================
--- core/tags/2.1.0.GA/src/main/java/org/jboss/cache/Version.java 2008-03-09 22:07:49 UTC (rev 5407)
+++ core/tags/2.1.0.GA/src/main/java/org/jboss/cache/Version.java 2008-03-09 22:11:12 UTC (rev 5408)
@@ -11,10 +11,10 @@
@Immutable
public class Version
{
- public static final String version = "2.1.0-SNAPSHOT";
+ public static final String version = "2.1.0.GA";
public static final String codename = "Alegrias";
//public static final String cvs = "$Id: Version.java 4592 2007-10-10 16:44:36Z manik.surtani(a)jboss.com $";
- static final byte[] version_id = {'0', '2', '1', '0', 'S'};
+ static final byte[] version_id = {'0', '2', '1', '0'};
private static final int MAJOR_SHIFT = 11;
private static final int MINOR_SHIFT = 6;
16 years, 10 months