[jbosscache-commits] JBoss Cache SVN: r6536 - in core/trunk/src: main/java/org/jboss/cache/buddyreplication and 8 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Aug 7 00:21:37 EDT 2008


Author: jason.greene at jboss.com
Date: 2008-08-07 00:21:36 -0400 (Thu, 07 Aug 2008)
New Revision: 6536

Added:
   core/trunk/src/main/java/org/jboss/cache/util/Immutables.java
Removed:
   core/trunk/src/main/java/org/jboss/cache/util/ImmutableMapCopy.java
   core/trunk/src/main/java/org/jboss/cache/util/ImmutableSetCopy.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/Fqn.java
   core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java
   core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
   core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyGroup.java
   core/trunk/src/main/java/org/jboss/cache/commands/read/GetDataMapCommand.java
   core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java
   core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
   core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java
   core/trunk/src/main/java/org/jboss/cache/loader/AsyncCacheLoader.java
   core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
   core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java
   core/trunk/src/main/java/org/jboss/cache/transaction/AbstractTransactionContext.java
   core/trunk/src/main/java/org/jboss/cache/util/ImmutableListCopy.java
   core/trunk/src/test/java/org/jboss/cache/util/ImmutableListCopyTest.java
Log:
Convert all immutable usage to new Immutables factory.
Drop ImmutableMapCopy and ImmutableSetCopy in favor of map/set wrappers
Add immutable wrappers which are detectable (unlike Collections.unmodifiable*)



Modified: core/trunk/src/main/java/org/jboss/cache/Fqn.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Fqn.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/Fqn.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -7,9 +7,6 @@
 package org.jboss.cache;
 
 
-import net.jcip.annotations.Immutable;
-import org.jboss.cache.util.ImmutableListCopy;
-
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -19,6 +16,10 @@
 import java.util.Collections;
 import java.util.List;
 
+import net.jcip.annotations.Immutable;
+
+import org.jboss.cache.util.Immutables;
+
 /**
  * A Fully Qualified Name (Fqn) is a list of names (typically Strings but can be any Object),
  * which represent a path to a particular {@link Node} or sometimes a {@link Region} in a {@link Cache}.
@@ -114,7 +115,7 @@
       if (names != null)
       {
          // if not safe make a defensive copy
-         elements = safe ? names : new ImmutableListCopy<Object>(names);
+         elements = safe ? names : Immutables.immutableListCopy(names);
          size = elements.size();
       }
       else
@@ -126,7 +127,7 @@
 
    protected Fqn(Fqn base, List<Object> relative)
    {
-      elements = new ImmutableListCopy<Object>(base.elements, relative);
+      elements = Immutables.immutableListMerge(base.elements, relative);
       size = elements.size();
    }
 
@@ -232,8 +233,8 @@
          return root();
 
       String toMatch = stringRepresentation.startsWith(SEPARATOR) ? stringRepresentation.substring(1) : stringRepresentation;
-      Object[] el = toMatch.split("/");
-      return new Fqn(new ImmutableListCopy(el), true);
+      Object[] el = toMatch.split(SEPARATOR);
+      return new Fqn(Immutables.immutableListWrap(el), true);
    }
 
    /**

Modified: core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -1,6 +1,13 @@
 package org.jboss.cache;
 
 import static org.jboss.cache.AbstractNode.NodeFlags.VALID;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
 import org.jboss.cache.commands.CommandsFactory;
 import org.jboss.cache.commands.legacy.write.CreateNodeCommand;
 import org.jboss.cache.invocation.InvocationContext;
@@ -9,14 +16,8 @@
 import org.jboss.cache.marshall.MarshalledValue;
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jboss.cache.util.FastCopyHashMap;
-import org.jboss.cache.util.ImmutableSetCopy;
+import org.jboss.cache.util.Immutables;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
 /**
  * UnversionedNode specific to pessimistic locking, with legacy code.
  *
@@ -290,7 +291,7 @@
       {
          if (children != null && !children.isEmpty())
          {
-            return new ImmutableSetCopy(children.values());
+            return Immutables.immutableSetConvert(children.values());
          }
          else
          {

Modified: core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/UnversionedNode.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -6,13 +6,11 @@
  */
 package org.jboss.cache;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import static org.jboss.cache.AbstractNode.NodeFlags.*;
-import org.jboss.cache.marshall.MarshalledValue;
-import org.jboss.cache.util.FastCopyHashMap;
-import org.jboss.cache.util.ImmutableSetCopy;
-import org.jboss.cache.util.concurrent.SelfInitializingConcurrentHashMap;
+import static org.jboss.cache.AbstractNode.NodeFlags.CHILDREN_LOADED;
+import static org.jboss.cache.AbstractNode.NodeFlags.DATA_LOADED;
+import static org.jboss.cache.AbstractNode.NodeFlags.LOCK_FOR_CHILD_INSERT_REMOVE;
+import static org.jboss.cache.AbstractNode.NodeFlags.REMOVED;
+import static org.jboss.cache.AbstractNode.NodeFlags.VALID;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -22,6 +20,13 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.marshall.MarshalledValue;
+import org.jboss.cache.util.FastCopyHashMap;
+import org.jboss.cache.util.Immutables;
+import org.jboss.cache.util.concurrent.SelfInitializingConcurrentHashMap;
+
 /**
  * Basic data node class.  Throws {@link UnsupportedOperationException} for version-specific methods like {@link #getVersion()} and
  * {@link #setVersion(org.jboss.cache.optimistic.DataVersion)}, defined in {@link org.jboss.cache.NodeSPI}.
@@ -208,7 +213,7 @@
       {
          if (!children.isEmpty())
          {
-            return new ImmutableSetCopy<InternalNode<K, V>>(children().values());
+            return Immutables.immutableSetConvert(children().values());
          }
          else
          {
@@ -370,9 +375,10 @@
       if (data != null) data.clear();
    }
 
+   @SuppressWarnings("unchecked")
    public Set<Object> getChildrenNames()
    {
-      return children.isEmpty() ? Collections.emptySet() : new ImmutableSetCopy<Object>(children.keySet());
+      return children.isEmpty() ? Collections.emptySet() : Immutables.immutableSetCopy(children.keySet());
    }
 
    public Set<K> getKeys()
@@ -381,7 +387,7 @@
       {
          return Collections.emptySet();
       }
-      return new ImmutableSetCopy<K>(data.keySet());
+      return Immutables.immutableSetCopy(data.keySet());
    }
 
    public boolean removeChild(Object childName)

Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyGroup.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyGroup.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyGroup.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -6,16 +6,17 @@
  */
 package org.jboss.cache.buddyreplication;
 
-import net.jcip.annotations.ThreadSafe;
-import org.jboss.cache.util.ImmutableListCopy;
-import org.jgroups.Address;
-
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import java.util.Vector;
 
+import net.jcip.annotations.ThreadSafe;
+
+import org.jboss.cache.util.Immutables;
+import org.jgroups.Address;
+
 /**
  * Value object that represents a buddy group
  *
@@ -65,7 +66,7 @@
    public List<Address> getBuddies()
    {
       // defensive copy and immutable.
-      return new ImmutableListCopy<Address>(buddies);
+      return Immutables.immutableListCopy(buddies);
    }
 
    protected void addBuddies(Collection<Address> buddies)

Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GetDataMapCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GetDataMapCommand.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GetDataMapCommand.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -4,7 +4,7 @@
 import org.jboss.cache.NodeSPI;
 import org.jboss.cache.commands.Visitor;
 import org.jboss.cache.invocation.InvocationContext;
-import org.jboss.cache.util.ImmutableMapCopy;
+import org.jboss.cache.util.Immutables;
 
 /**
  * Implements functionality defined by {@link org.jboss.cache.Cache#getData(org.jboss.cache.Fqn)}
@@ -35,9 +35,9 @@
     */
    public Object perform(InvocationContext ctx)
    {
-      NodeSPI n = ctx.lookUpNode(fqn);
+      NodeSPI<?,?> n = ctx.lookUpNode(fqn);
       if (n == null || n.isDeleted()) return null;
-      return new ImmutableMapCopy(n.getDataDirect());
+      return Immutables.immutableMapCopy(n.getDataDirect());
    }
 
    public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/AbstractInvocationContext.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -6,6 +6,12 @@
  */
 package org.jboss.cache.invocation;
 
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import javax.transaction.Transaction;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.commands.VisitableCommand;
@@ -14,13 +20,8 @@
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jboss.cache.transaction.TransactionContext;
 import org.jboss.cache.transaction.TransactionTable;
-import org.jboss.cache.util.ImmutableListCopy;
+import org.jboss.cache.util.Immutables;
 
-import javax.transaction.Transaction;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-
 /**
  * This context holds information specific to a method invocation.  This is used for Optimistic and Pessimisic Node Locking Schemes.
  *
@@ -117,7 +118,7 @@
    {
       // first check transactional scope
       if (transactionContext != null) return transactionContext.getLocks();
-      return invocationLocks == null || invocationLocks.isEmpty() ? Collections.emptyList() : new ImmutableListCopy(invocationLocks);
+      return invocationLocks == null || invocationLocks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(invocationLocks);
    }
 
    @SuppressWarnings("unchecked")

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/CacheInvocationDelegate.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -1,5 +1,13 @@
 package org.jboss.cache.invocation;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.CacheException;
@@ -31,8 +39,8 @@
 import org.jboss.cache.commands.write.RemoveKeyCommand;
 import org.jboss.cache.commands.write.RemoveNodeCommand;
 import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.Option;
 import org.jboss.cache.config.Configuration.NodeLockingScheme;
-import org.jboss.cache.config.Option;
 import org.jboss.cache.factories.annotations.Inject;
 import org.jboss.cache.factories.annotations.NonVolatile;
 import org.jboss.cache.factories.annotations.Start;
@@ -44,16 +52,9 @@
 import org.jboss.cache.statetransfer.StateTransferManager;
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jboss.cache.transaction.TransactionTable;
-import org.jboss.cache.util.ImmutableSetCopy;
+import org.jboss.cache.util.Immutables;
 import org.jgroups.Address;
 
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * The delegate that users (and ChainedInterceptor authors) interact with when they create a cache by using a cache factory.
  * This wrapper delegates calls down the interceptor chain.
@@ -589,7 +590,7 @@
       GetChildrenNamesCommand command = commandsFactory.buildGetChildrenNamesCommand(fqn);
       Set<Object> retval = (Set<Object>) invoker.invoke(ctx, command);
       if (retval != null)
-         retval = new ImmutableSetCopy<Object>(retval);
+         retval = Immutables.immutableSetWrap(retval); // this is already copied in the command
       else
          retval = Collections.emptySet();
       return retval;

Modified: core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/loader/AbstractCacheLoader.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -6,6 +6,14 @@
  */
 package org.jboss.cache.loader;
 
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.CacheException;
@@ -20,16 +28,8 @@
 import org.jboss.cache.marshall.NodeData;
 import org.jboss.cache.marshall.NodeDataExceptionMarker;
 import org.jboss.cache.marshall.NodeDataMarker;
-import org.jboss.cache.util.ImmutableMapCopy;
+import org.jboss.cache.util.Immutables;
 
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
 /**
  * A convenience abstract implementation of a {@link CacheLoader}.  Specific methods to note are methods like
  * {@link #storeState(org.jboss.cache.Fqn,java.io.ObjectInputStream)}, {@link #loadState(org.jboss.cache.Fqn,java.io.ObjectOutputStream)},
@@ -64,7 +64,7 @@
       }
 
       // JBCACHE-769 -- make a defensive copy
-      Map<Object, Object> attrs = (attributes == null ? null : new ImmutableMapCopy<Object, Object>(attributes));
+      Map<Object, Object> attrs = (attributes == null ? null : Immutables.immutableMapCopy(attributes));
       put(fqn, attrs);
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/loader/AsyncCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/AsyncCacheLoader.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/loader/AsyncCacheLoader.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -3,14 +3,6 @@
  */
 package org.jboss.cache.loader;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Modification;
-import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
-import org.jboss.cache.util.ImmutableMapCopy;
-
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -26,6 +18,14 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Modification;
+import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+import org.jboss.cache.util.Immutables;
+
 /**
  * The AsyncCacheLoader is a delegating cache loader that extends
  * AbstractDelegatingCacheLoader overriding methods to that should not
@@ -191,7 +191,7 @@
       if (config.getUseAsyncPut())
       {
          // JBCACHE-769 -- make a defensive copy
-         Map attrs = (attributes == null ? null : new ImmutableMapCopy(attributes));
+         Map attrs = (attributes == null ? null : Immutables.immutableMapCopy(attributes));
          Modification mod = new Modification(Modification.ModificationType.PUT_DATA, name, attrs);
          enqueue(mod);
       }

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -6,20 +6,6 @@
  */
 package org.jboss.cache.marshall;
 
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Region;
-import static org.jboss.cache.Region.Status;
-import org.jboss.cache.buddyreplication.GravitateResult;
-import org.jboss.cache.commands.CommandsFactory;
-import org.jboss.cache.commands.ReplicableCommand;
-import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.optimistic.DefaultDataVersion;
-import org.jboss.cache.transaction.GlobalTransaction;
-import org.jboss.cache.util.FastCopyHashMap;
-import org.jboss.cache.util.ImmutableMapCopy;
-import org.jgroups.Address;
-import org.jgroups.stack.IpAddress;
-
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInputStream;
@@ -36,6 +22,20 @@
 import java.util.TreeMap;
 import java.util.TreeSet;
 
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Region;
+import org.jboss.cache.Region.Status;
+import org.jboss.cache.buddyreplication.GravitateResult;
+import org.jboss.cache.commands.CommandsFactory;
+import org.jboss.cache.commands.ReplicableCommand;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.optimistic.DefaultDataVersion;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.util.FastCopyHashMap;
+import org.jboss.cache.util.Immutables;
+import org.jgroups.Address;
+import org.jgroups.stack.IpAddress;
+
 /**
  * An enhanced marshaller for RPC calls between CacheImpl instances.
  *
@@ -349,7 +349,7 @@
          out.writeByte(MAGICNUMBER_FASTCOPY_HASHMAP);
          marshallMap((Map) o, out, refMap);
       }
-      else if (o.getClass().equals(ImmutableMapCopy.class))
+      else if (o instanceof Map && Immutables.isImmutable(o))
       {
          out.writeByte(MAGICNUMBER_IMMUTABLE_MAPCOPY);
          marshallMap((Map) o, out, refMap);
@@ -748,7 +748,7 @@
    {
       // read in as a HashMap first
       Map m = unmarshallHashMap(in, refMap);
-      return new ImmutableMapCopy(m);
+      return Immutables.immutableMapWrap(m);
    }
 
    private Map unmarshallTreeMap(ObjectInputStream in, UnmarshalledReferences refMap) throws Exception

Modified: core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/notifications/NotifierImpl.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -6,6 +6,43 @@
  */
 package org.jboss.cache.notifications;
 
+import static org.jboss.cache.notifications.event.Event.Type.BUDDY_GROUP_CHANGED;
+import static org.jboss.cache.notifications.event.Event.Type.CACHE_BLOCKED;
+import static org.jboss.cache.notifications.event.Event.Type.CACHE_STARTED;
+import static org.jboss.cache.notifications.event.Event.Type.CACHE_STOPPED;
+import static org.jboss.cache.notifications.event.Event.Type.CACHE_UNBLOCKED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_ACTIVATED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_CREATED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_EVICTED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_INVALIDATED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_LOADED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_MODIFIED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_MOVED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_PASSIVATED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_REMOVED;
+import static org.jboss.cache.notifications.event.Event.Type.NODE_VISITED;
+import static org.jboss.cache.notifications.event.Event.Type.TRANSACTION_COMPLETED;
+import static org.jboss.cache.notifications.event.Event.Type.TRANSACTION_REGISTERED;
+import static org.jboss.cache.notifications.event.Event.Type.VIEW_CHANGED;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.transaction.Transaction;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.jboss.cache.Cache;
@@ -21,30 +58,49 @@
 import org.jboss.cache.factories.annotations.Stop;
 import org.jboss.cache.invocation.InvocationContext;
 import org.jboss.cache.marshall.MarshalledValueMap;
-import org.jboss.cache.notifications.annotation.*;
-import org.jboss.cache.notifications.event.*;
-import static org.jboss.cache.notifications.event.Event.Type.*;
-import org.jboss.cache.util.ImmutableMapCopy;
+import org.jboss.cache.notifications.annotation.BuddyGroupChanged;
+import org.jboss.cache.notifications.annotation.CacheBlocked;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.CacheStarted;
+import org.jboss.cache.notifications.annotation.CacheStopped;
+import org.jboss.cache.notifications.annotation.CacheUnblocked;
+import org.jboss.cache.notifications.annotation.NodeActivated;
+import org.jboss.cache.notifications.annotation.NodeCreated;
+import org.jboss.cache.notifications.annotation.NodeEvicted;
+import org.jboss.cache.notifications.annotation.NodeInvalidated;
+import org.jboss.cache.notifications.annotation.NodeLoaded;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.NodeMoved;
+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.annotation.TransactionCompleted;
+import org.jboss.cache.notifications.annotation.TransactionRegistered;
+import org.jboss.cache.notifications.annotation.ViewChanged;
+import org.jboss.cache.notifications.event.BuddyGroupChangedEvent;
+import org.jboss.cache.notifications.event.CacheBlockedEvent;
+import org.jboss.cache.notifications.event.CacheStartedEvent;
+import org.jboss.cache.notifications.event.CacheStoppedEvent;
+import org.jboss.cache.notifications.event.CacheUnblockedEvent;
+import org.jboss.cache.notifications.event.Event;
+import org.jboss.cache.notifications.event.EventImpl;
+import org.jboss.cache.notifications.event.NodeActivatedEvent;
+import org.jboss.cache.notifications.event.NodeCreatedEvent;
+import org.jboss.cache.notifications.event.NodeEvictedEvent;
+import org.jboss.cache.notifications.event.NodeInvalidatedEvent;
+import org.jboss.cache.notifications.event.NodeLoadedEvent;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodeMovedEvent;
+import org.jboss.cache.notifications.event.NodePassivatedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
+import org.jboss.cache.notifications.event.NodeVisitedEvent;
+import org.jboss.cache.notifications.event.TransactionCompletedEvent;
+import org.jboss.cache.notifications.event.TransactionRegisteredEvent;
+import org.jboss.cache.notifications.event.ViewChangedEvent;
+import org.jboss.cache.util.Immutables;
 import org.jboss.cache.util.concurrent.WithinThreadExecutor;
 import org.jgroups.View;
 
-import javax.transaction.Transaction;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicInteger;
-
 /**
  * Helper class that handles all notifications to registered listeners.
  *
@@ -606,7 +662,7 @@
       if (data == null) return null;
       if (data.isEmpty()) return Collections.emptyMap();
       if (safe(data)) return useMarshalledValueMaps ? new MarshalledValueMap(data) : data;
-      Map defensivelyCopiedData = new ImmutableMapCopy(data);
+      Map defensivelyCopiedData = Immutables.immutableMapCopy(data);
       return useMarshalledValueMaps ? new MarshalledValueMap(defensivelyCopiedData) : defensivelyCopiedData;
    }
 
@@ -643,7 +699,7 @@
     */
    private static boolean safe(Map map)
    {
-      return map == null || map instanceof ImmutableMapCopy || map.getClass().equals(emptyMap) || map.getClass().equals(singletonMap);
+      return map == null || Immutables.isImmutable(map) || map.getClass().equals(emptyMap) || map.getClass().equals(singletonMap);
    }
 
    /**

Modified: core/trunk/src/main/java/org/jboss/cache/transaction/AbstractTransactionContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/AbstractTransactionContext.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/AbstractTransactionContext.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -7,21 +7,22 @@
 package org.jboss.cache.transaction;
 
 
-import org.jboss.cache.Fqn;
-import org.jboss.cache.commands.WriteCommand;
-import org.jboss.cache.config.Option;
-import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
-import org.jboss.cache.util.ImmutableListCopy;
-
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.commands.WriteCommand;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
+import org.jboss.cache.util.Immutables;
+
 /**
  * An abstract transaction context
  */
@@ -159,7 +160,7 @@
    @SuppressWarnings("unchecked")
    public List getLocks()
    {
-      return transactionLocks == null || transactionLocks.isEmpty() ? Collections.emptyList() : new ImmutableListCopy(transactionLocks);
+      return transactionLocks == null || transactionLocks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(transactionLocks);
    }
 
 

Modified: core/trunk/src/main/java/org/jboss/cache/util/ImmutableListCopy.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/ImmutableListCopy.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/util/ImmutableListCopy.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -29,7 +29,7 @@
  * @since 3.0
  */
 @Immutable
-public class ImmutableListCopy<E> extends AbstractList<E> implements Externalizable
+public class ImmutableListCopy<E> extends AbstractList<E> implements Externalizable, Immutables.Immutable
 {
    private static final long serialVersionUID = 10929568968966L;
    private E[] elements;

Deleted: core/trunk/src/main/java/org/jboss/cache/util/ImmutableMapCopy.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/ImmutableMapCopy.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/util/ImmutableMapCopy.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -1,149 +0,0 @@
-package org.jboss.cache.util;
-
-import net.jcip.annotations.Immutable;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.AbstractMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Along the lines of ImmutableListCopy and ImmutableSetCopy.  This lightweight wrapper primarily meant for iteration.
- * performance of get() and containsKey() are not as efficient as that of a {@link java.util.HashMap}, but iteration is
- * fast since the entry table is a fixed size immutable array.
- * <p/>
- * Typically used in place of the common idiom:
- * <code>
- * return Collections.unmodifiableMap(new HashMap( myInternalMap ));
- * </code>
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 3.0
- */
- at Immutable
-public class ImmutableMapCopy<K, V> extends AbstractMap<K, V> implements Externalizable // externalizable for client code that may serialize this map
-{
-   private static final long serialVersionUID = 10929568968766L;
-   private Entry<K, V>[] table;
-   private int size;
-
-   /**
-    * For Externalizable
-    */
-   public ImmutableMapCopy()
-   {
-   }
-
-   @SuppressWarnings("unchecked")
-   public ImmutableMapCopy(Map<K, V> map)
-   {
-      size = map.size();
-      table = new ImmutableEntry[size];
-      int i = 0;
-      for (Map.Entry<K, V> me : map.entrySet())
-      {
-         table[i++] = new ImmutableEntry<K, V>(me);
-      }
-   }
-
-   @Override
-   public int size()
-   {
-      return size;
-   }
-
-   @Override
-   public final V remove(Object key)
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
-   public final void putAll(Map<? extends K, ? extends V> t)
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
-   public final void clear()
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   public final Set<Entry<K, V>> entrySet()
-   {
-      return new ImmutableSetCopy<Map.Entry<K, V>>(table);
-   }
-
-   /**
-    * Format:
-    * - entry array size (int)
-    * - entry key-value pairs (Object, Object)
-    *
-    * @param out stream to write to
-    * @throws IOException
-    */
-   public void writeExternal(ObjectOutput out) throws IOException
-   {
-      out.writeInt(size);
-      for (Entry e : table)
-      {
-         out.writeObject(e.getKey());
-         out.writeObject(e.getValue());
-      }
-   }
-
-   /**
-    * See {@link #writeExternal(java.io.ObjectOutput)} for serialization format
-    *
-    * @param in stream
-    * @throws IOException
-    * @throws ClassNotFoundException
-    */
-   @SuppressWarnings("unchecked")
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
-   {
-      size = in.readInt();
-      table = new Entry[size];
-      for (int i = 0; i < size; i++)
-      {
-         table[i] = new ImmutableEntry(in.readObject(), in.readObject());
-      }
-   }
-
-   private static class ImmutableEntry<K, V> implements Map.Entry<K, V>
-   {
-      K k;
-      V v;
-
-      private ImmutableEntry(Map.Entry<K, V> entry)
-      {
-         k = entry.getKey();
-         v = entry.getValue();
-      }
-
-      private ImmutableEntry(K k, V v)
-      {
-         this.k = k;
-         this.v = v;
-      }
-
-      public K getKey()
-      {
-         return k;
-      }
-
-      public V getValue()
-      {
-         return v;
-      }
-
-      public V setValue(V value)
-      {
-         throw new UnsupportedOperationException();
-      }
-   }
-}

Deleted: core/trunk/src/main/java/org/jboss/cache/util/ImmutableSetCopy.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/ImmutableSetCopy.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/main/java/org/jboss/cache/util/ImmutableSetCopy.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -1,143 +0,0 @@
-package org.jboss.cache.util;
-
-import net.jcip.annotations.Immutable;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * This is based on an ImmutableListCopy, with the assumption that the set passed in would ensure uniqueness of elements.
- * <p/>
- * The constructor takes in a collection so the onus is on the caller to ensure that the collection passed in adheres to
- * Set semantics.
- * <p/>
- * Typically used in place of the common idiom:
- * <code>
- * return Collections.unmodifiableSet(new HashSet( myInternalSet ));
- * </code>
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @see org.jboss.cache.util.ImmutableListCopy
- * @since 3.0
- */
- at Immutable
-public class ImmutableSetCopy<E> extends AbstractSet<E> implements Externalizable
-{
-   private static final long serialVersionUID = 11929568968766L;
-   private E[] elements;
-   private int size;
-
-   @SuppressWarnings("unchecked")
-   public ImmutableSetCopy(Collection<E> set)
-   {
-      size = set.size();
-      E[] tempElements = (E[]) new Object[size]; // no room for growth
-      elements = set.toArray(tempElements);
-   }
-
-   /**
-    * Assumes that the array passed in is "safe", i.e., is not referenced from elsewhere.  Also assumes the array contains
-    * elements such that the uniqueness required by a set is adhered to.  Use with care!
-    *
-    * @param array to reference
-    */
-   public ImmutableSetCopy(E[] array)
-   {
-      elements = array;
-      size = elements.length;
-   }
-
-   @Override
-   public boolean remove(Object o)
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
-   public boolean addAll(Collection<? extends E> c)
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
-   public boolean retainAll(Collection<?> c)
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
-   public boolean removeAll(Collection<?> c)
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
-   public void clear()
-   {
-      throw new UnsupportedOperationException();
-   }
-
-   public Iterator<E> iterator()
-   {
-      return new Iterator<E>()
-      {
-         int cursor = 0;
-
-         public boolean hasNext()
-         {
-            return cursor < size;
-         }
-
-         public E next()
-         {
-            if (cursor >= size) throw new NoSuchElementException();
-            return elements[cursor++];
-         }
-
-         public void remove()
-         {
-            throw new UnsupportedOperationException();
-         }
-      };
-   }
-
-   public int size()
-   {
-      return size;
-   }
-
-   /**
-    * Format:
-    * - entry array size (int)
-    * - elements (Object)
-    *
-    * @param out stream to write to
-    * @throws IOException
-    */
-   public void writeExternal(ObjectOutput out) throws IOException
-   {
-      out.writeInt(size);
-      for (E e : elements) out.writeObject(e);
-   }
-
-   /**
-    * See {@link #writeExternal(java.io.ObjectOutput)} for serialization format
-    *
-    * @param in stream
-    * @throws IOException
-    * @throws ClassNotFoundException
-    */
-   @SuppressWarnings("unchecked")
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
-   {
-      size = in.readInt();
-      elements = (E[]) new Object[size];
-      for (int i = 0; i < size; i++) elements[i] = (E) in.readObject();
-   }
-}

Added: core/trunk/src/main/java/org/jboss/cache/util/Immutables.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/Immutables.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/util/Immutables.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -0,0 +1,541 @@
+/*
+* 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.util;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * Factory for generating immutable type wrappers.
+ *
+ * @author Jason T. Greene
+ */
+public class Immutables
+{
+   /**
+    * Whether or not this collection type is immutable
+    *
+    * @param a Collection, Set, List, or Map
+    * @return true if immutable, false if not
+    */
+   public static boolean isImmutable(Object o)
+   {
+      return o instanceof Immutable;
+   }
+
+   /**
+    * Converts a Collection to an immutable List by copying it.
+    *
+    * @param source the collection to convert
+    * @return a copied/converted immutable list
+    */
+   public static <T> List<T> immutableListConvert(Collection<? extends T> source)
+   {
+      return new ImmutableListCopy<T>(source);
+   }
+
+   /**
+    * Creates an immutable copy of the list.
+    *
+    * @param list the list to copy
+    * @return the immutable copy
+    */
+   public static <T> List<T> immutableListCopy(List<? extends T> list)
+   {
+      return new ImmutableListCopy<T>(list);
+   }
+
+   /**
+    * Wraps an array with an immutable list. There is no copying involved.
+    *
+    * @param <T>
+    * @param array the array to wrap
+    * @return a list containing the array
+    */
+   public static <T> List<T> immutableListWrap(T... array)
+   {
+      return new ImmutableListCopy<T>(array);
+   }
+
+   /**
+    * Creates a new immutable list containing the union (combined entries) of both lists.
+    *
+    * @param list1 contains the first elements of the new list
+    * @param list2 contains the successor elements of the new list
+    * @return a new immutable merged copy of list1 and list2
+    */
+   public static <T> List<T> immutableListMerge(List<? extends T> list1, List<? extends T> list2)
+   {
+      return new ImmutableListCopy<T>(list1, list2);
+   }
+
+   /**
+    * Converts a Collections into an immutable Set by copying it.
+    *
+    * @param collection the collection to convert/copy
+    * @return a new immutable set containing the elements in collection
+    */
+   public static <T> Set<T> immutableSetConvert(Collection<? extends T> collection)
+   {
+      return immutableSetWrap(new HashSet<T>(collection));
+   }
+
+   /**
+    * Wraps a set with an immutable set. There is no copying involved.
+    *
+    * @param set the set to wrap
+    * @return an immutable set wrapper that delegates to the original set
+    */
+   public static <T> Set<T> immutableSetWrap(Set<? extends T> set)
+   {
+      return new ImmutableSetWrapper<T>(set);
+   }
+
+   /**
+    * Creates an immutable copy of the specified set.
+    *
+    * @param set the set to copy from
+    * @return an immutable set copy
+    */
+   public static <T> Set<T> immutableSetCopy(Set<? extends T> set)
+   {
+      Set<? extends T> copy = attemptClone(set);
+      if (copy == null)
+         // Set uses Collection copy-ctor
+         copy = attemptCopyConstructor(set, Collection.class);
+
+      if (copy == null)
+         copy = new HashSet<T>(set);
+
+      return new ImmutableSetWrapper<T>(copy);
+   }
+
+
+   /**
+    * Wraps a map with an immutable map. There is no copying involved.
+    *
+    * @param map the map to wrap
+    * @return an immutable map wrapper that delegates to the original map
+    */
+   public static <K,V> Map<K,V> immutableMapWrap(Map<? extends K, ? extends V> map)
+   {
+      return new ImmutableMapWrapper<K,V>(map);
+   }
+
+   /**
+    * Creates an immutable copy of the specified map.
+    *
+    * @param map the map to copy from
+    * @return an immutable map copy
+    */
+   public static <K,V> Map<K,V> immutableMapCopy(Map<? extends K, ? extends V> map)
+   {
+      Map<? extends K, ? extends V> copy = attemptClone(map);
+      if (copy == null)
+         copy = attemptCopyConstructor(map, Map.class);
+      if (copy == null)
+         copy = new HashMap<K,V>(map);
+
+      return new ImmutableMapWrapper<K,V>(map);
+   }
+
+   /**
+    * Creates a new immutable copy of the specified Collection.
+    *
+    * @param collection the collection to copy
+    * @return an immutable copy
+    */
+   public static <T> Collection<T> immutableCollectionCopy(Collection<? extends T> collection)
+   {
+      Collection<? extends T> copy = attemptClone(collection);
+      if (copy == null)
+         copy = attemptCopyConstructor(collection, Collection.class);
+      if (copy == null)
+         copy = new ArrayList<T>(collection);
+
+      return new ImmutableCollectionWrapper<T>(collection);
+   }
+
+
+   @SuppressWarnings("unchecked")
+   private static <T> T attemptClone(T source)
+   {
+      if (source instanceof Cloneable)
+      {
+         try
+         {
+            return (T) source.getClass().getMethod("clone").invoke(source);
+         }
+         catch (Exception e)
+         {
+         }
+      }
+
+      return null;
+   }
+
+   @SuppressWarnings("unchecked")
+   private static <T> T attemptCopyConstructor(T source, Class<? super T> clazz)
+   {
+      try
+      {
+         return (T) source.getClass().getConstructor(clazz).newInstance(source);
+      }
+      catch (Exception e)
+      {
+      }
+
+      return null;
+   }
+
+
+   public interface Immutable
+   {
+   }
+
+   /*
+    * Immutable wrapper types.
+    *
+    * We have to re-implement Collections.unmodifiableXXX, since it is not
+    * simple to detect them (the class names are JDK dependent).
+    */
+
+   private static class ImmutableIteratorWrapper<E> implements Iterator<E>
+   {
+      private Iterator<? extends E> iterator;
+
+      public ImmutableIteratorWrapper(Iterator<? extends E> iterator)
+      {
+         this.iterator = iterator;
+      }
+
+      public boolean hasNext()
+      {
+         return iterator.hasNext();
+      }
+
+      public E next()
+      {
+         return iterator.next();
+      }
+
+      public void remove()
+      {
+         throw new UnsupportedOperationException();
+      }
+   }
+
+   private static class ImmutableCollectionWrapper<E> implements Collection<E>, Serializable, Immutable
+   {
+      private static final long serialVersionUID = 6777564328198393535L;
+
+      Collection<? extends E> collection;
+
+      public ImmutableCollectionWrapper(Collection<? extends E> collection)
+      {
+         this.collection = collection;
+      }
+
+      public boolean add(E o)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public boolean addAll(Collection<? extends E> c)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public void clear()
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public boolean contains(Object o)
+      {
+         return collection.contains(o);
+      }
+
+      public boolean containsAll(Collection<?> c)
+      {
+         return collection.containsAll(c);
+      }
+
+      public boolean equals(Object o)
+      {
+         return collection.equals(o);
+      }
+
+      public int hashCode()
+      {
+         return collection.hashCode();
+      }
+
+      public boolean isEmpty()
+      {
+         return collection.isEmpty();
+      }
+
+      public Iterator<E> iterator()
+      {
+         return new ImmutableIteratorWrapper<E>(collection.iterator());
+      }
+
+      public boolean remove(Object o)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public boolean removeAll(Collection<?> c)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public boolean retainAll(Collection<?> c)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public int size()
+      {
+         return collection.size();
+      }
+
+      public Object[] toArray()
+      {
+         return collection.toArray();
+      }
+
+      public <T> T[] toArray(T[] a)
+      {
+         return collection.toArray(a);
+      }
+
+      public String toString()
+      {
+         return collection.toString();
+      }
+   }
+
+
+
+   private static class ImmutableSetWrapper<E> extends ImmutableCollectionWrapper<E> implements Set<E>, Serializable, Immutable
+   {
+      private static final long serialVersionUID = 7991492805176142615L;
+
+      public ImmutableSetWrapper(Set<? extends E> set)
+      {
+         super(set);
+      }
+   }
+
+
+   static class ImmutableEntry<K, V> implements Map.Entry<K, V>
+   {
+      private K key;
+      private V value;
+      private int hash;
+
+      ImmutableEntry(Map.Entry<? extends K, ? extends V> entry)
+      {
+         this.key = entry.getKey();
+         this.value = entry.getValue();
+         this.hash = entry.hashCode();
+      }
+
+      public K getKey()
+      {
+         return key;
+      }
+
+      public V getValue()
+      {
+         return value;
+      }
+
+      public V setValue(V value)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      private static boolean eq(Object o1, Object o2)
+      {
+         return o1 == o2 || (o1 != null && o1.equals(o2));
+      }
+
+      @SuppressWarnings("unchecked")
+      public boolean equals(Object o)
+      {
+         if (! (o instanceof Map.Entry))
+            return false;
+
+         Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
+         return eq(entry.getKey(), key) && eq(entry.getValue(), value);
+      }
+
+      public int hashCode()
+      {
+         return hash;
+      }
+
+      public String toString()
+      {
+         return getKey() + "=" + getValue();
+      }
+   }
+
+   private static class ImmutableEntrySetWrapper<K,V> extends ImmutableSetWrapper<Map.Entry<K, V>>
+   {
+      private static final long serialVersionUID = 6378667653889667692L;
+
+      @SuppressWarnings("unchecked")
+      public ImmutableEntrySetWrapper(Set<? extends Map.Entry<? extends K, ? extends V>> set)
+      {
+         super((Set<Entry<K, V>>)set);
+      }
+
+      public Object[] toArray()
+      {
+         Object[] array = new Object[collection.size()];
+         int i = 0;
+         for (Map.Entry<K, V> entry : this)
+            array[i++] = entry;
+         return array;
+      }
+
+      @SuppressWarnings("unchecked")
+      public <T> T[] toArray(T[] array)
+      {
+         int size = collection.size();
+         if (array.length < size)
+            array = (T[]) Array.newInstance(array.getClass().getComponentType(), size);
+
+         int i = 0;
+         Object[] result = array;
+         for (Map.Entry<K, V> entry : this)
+            result[i++] = entry;
+
+         return array;
+      }
+
+      public Iterator<Map.Entry<K,V>> iterator()
+      {
+         return new ImmutableIteratorWrapper<Entry<K,V>>(collection.iterator()) {
+            public Entry<K, V> next()
+            {
+               return new ImmutableEntry<K,V>(super.next());
+            }
+         };
+      }
+   }
+
+   private static class ImmutableMapWrapper<K,V> implements Map<K,V>, Serializable, Immutable
+   {
+      private static final long serialVersionUID = 708144227046742221L;
+
+      private Map<? extends K, ? extends V> map;
+
+      public ImmutableMapWrapper(Map<? extends K, ? extends V> map)
+      {
+         this.map = map;
+      }
+
+      public void clear()
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public boolean containsKey(Object key)
+      {
+         return map.containsKey(key);
+      }
+
+      public boolean containsValue(Object value)
+      {
+         return map.containsValue(value);
+      }
+
+      public Set<Entry<K, V>> entrySet()
+      {
+         return new ImmutableEntrySetWrapper<K,V>(map.entrySet());
+      }
+
+      public boolean equals(Object o)
+      {
+         return map.equals(o);
+      }
+
+      public V get(Object key)
+      {
+         return map.get(key);
+      }
+
+      public int hashCode()
+      {
+         return map.hashCode();
+      }
+
+      public boolean isEmpty()
+      {
+         return map.isEmpty();
+      }
+
+      public Set<K> keySet()
+      {
+         return new ImmutableSetWrapper<K>(map.keySet());
+      }
+
+      public V put(K key, V value)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public void putAll(Map<? extends K, ? extends V> t)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public V remove(Object key)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      public int size()
+      {
+         return map.size();
+      }
+
+      public Collection<V> values()
+      {
+         return new ImmutableCollectionWrapper<V>(map.values());
+      }
+   }
+}

Modified: core/trunk/src/test/java/org/jboss/cache/util/ImmutableListCopyTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/util/ImmutableListCopyTest.java	2008-08-06 16:17:53 UTC (rev 6535)
+++ core/trunk/src/test/java/org/jboss/cache/util/ImmutableListCopyTest.java	2008-08-07 04:21:36 UTC (rev 6536)
@@ -12,7 +12,7 @@
 {
    public void testImmutability()
    {
-      List<String> l = new ImmutableListCopy<String>(Collections.singletonList("one"));
+      List<String> l = Immutables.immutableListCopy(Collections.singletonList("one"));
       try
       {
          l.add("two");
@@ -126,10 +126,8 @@
 
    public void testListIterator()
    {
-      List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+      List<Integer> list = Immutables.immutableListWrap(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
 
-      List<Integer> list = new ImmutableListCopy<Integer>(ints);
-
       ListIterator<Integer> li = list.listIterator();
 
       int number = 1;
@@ -145,7 +143,7 @@
    public void testSubLists()
    {
       List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
-      List<Integer> list = new ImmutableListCopy<Integer>(ints);
+      List<Integer> list = Immutables.immutableListCopy(ints);
 
       assert ints.subList(2, 5).equals(list.subList(2, 5));
       assert ints.subList(1, 9).equals(list.subList(1, 9));




More information about the jbosscache-commits mailing list