[jbosscache-commits] JBoss Cache SVN: r6754 - in core/trunk/src: test/java/org/jboss/cache/marshall and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Sep 18 13:18:38 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-09-18 13:18:38 -0400 (Thu, 18 Sep 2008)
New Revision: 6754

Added:
   core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller300.java
   core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller300Test.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
   core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java
   core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java
   core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java
Log:
JBCACHE-1411 :  Marshaller has no special treatment of arrays, even arrays of primitives or known types

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java	2008-09-18 16:03:00 UTC (rev 6753)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller200.java	2008-09-18 17:18:38 UTC (rev 6754)
@@ -6,6 +6,21 @@
  */
 package org.jboss.cache.marshall;
 
+import org.jboss.cache.CacheException;
+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;
+
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInputStream;
@@ -22,20 +37,6 @@
 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.
  *
@@ -67,6 +68,12 @@
    protected static final int MAGICNUMBER_IMMUTABLE_MAPCOPY = 21;
    protected static final int MAGICNUMBER_MARSHALLEDVALUE = 22;
    protected static final int MAGICNUMBER_FASTCOPY_HASHMAP = 23;
+   protected static final int MAGICNUMBER_ARRAY = 24;
+   protected static final int MAGICNUMBER_BYTE = 25;
+   protected static final int MAGICNUMBER_CHAR = 26;
+   protected static final int MAGICNUMBER_FLOAT = 27;
+   protected static final int MAGICNUMBER_DOUBLE = 28;
+   protected static final int MAGICNUMBER_OBJECT = 29;
    protected static final int MAGICNUMBER_NULL = 99;
    protected static final int MAGICNUMBER_SERIALIZABLE = 100;
    protected static final int MAGICNUMBER_REF = 101;
@@ -582,6 +589,8 @@
          case MAGICNUMBER_DEFAULT_DATA_VERSION:
             retVal = unmarshallDefaultDataVersion(in);
             return retVal;
+         case MAGICNUMBER_ARRAY:
+            return unmarshallArray(in, refMap);
          case MAGICNUMBER_ARRAY_LIST:
             return unmarshallArrayList(in, refMap);
          case MAGICNUMBER_LINKED_LIST:
@@ -847,5 +856,150 @@
    {
       out.writeLong(i);
    }
+
+   protected Object unmarshallArray(ObjectInputStream in, UnmarshalledReferences refs) throws Exception
+   {
+      int sz = readUnsignedInt(in);
+      byte type = in.readByte();
+      switch (type)
+      {
+         case MAGICNUMBER_BOOLEAN:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               boolean[] a = new boolean[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readBoolean();
+               return a;
+            }
+            else
+            {
+               Boolean[] a = new Boolean[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readBoolean();
+               return a;
+            }
+         }
+         case MAGICNUMBER_INTEGER:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               int[] a = new int[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readInt();
+               return a;
+            }
+            else
+            {
+               Integer[] a = new Integer[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readInt();
+               return a;
+            }
+         }
+         case MAGICNUMBER_LONG:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               long[] a = new long[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readLong();
+               return a;
+            }
+            else
+            {
+               Long[] a = new Long[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readLong();
+               return a;
+            }
+         }
+         case MAGICNUMBER_CHAR:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               char[] a = new char[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readChar();
+               return a;
+            }
+            else
+            {
+               Character[] a = new Character[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readChar();
+               return a;
+            }
+         }
+         case MAGICNUMBER_BYTE:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               byte[] a = new byte[sz];
+               in.read(a);
+               return a;
+            }
+            else
+            {
+               Byte[] a = new Byte[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readByte();
+               return a;
+            }
+         }
+         case MAGICNUMBER_SHORT:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               short[] a = new short[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readShort();
+               return a;
+            }
+            else
+            {
+               Short[] a = new Short[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readShort();
+               return a;
+            }
+         }
+         case MAGICNUMBER_FLOAT:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               float[] a = new float[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readFloat();
+               return a;
+            }
+            else
+            {
+               Float[] a = new Float[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readFloat();
+               return a;
+            }
+         }
+         case MAGICNUMBER_DOUBLE:
+         {
+            boolean isPrim = in.readBoolean();
+            if (isPrim)
+            {
+               double[] a = new double[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readDouble();
+               return a;
+            }
+            else
+            {
+               Double[] a = new Double[sz];
+               for (int i = 0; i < sz; i++) a[i] = in.readDouble();
+               return a;
+            }
+         }
+         case MAGICNUMBER_OBJECT:
+         {
+            Object[] a = new Object[sz];
+            for (int i = 0; i < sz; i++) a[i] = unmarshallObject(in, refs);
+            return a;
+         }
+         default:
+            throw new CacheException("Unknown array type");
+      }
+   }
 }
 

Added: core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller300.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller300.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/CacheMarshaller300.java	2008-09-18 17:18:38 UTC (rev 6754)
@@ -0,0 +1,126 @@
+package org.jboss.cache.marshall;
+
+import org.jboss.cache.CacheException;
+
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Array;
+import java.util.Map;
+
+/**
+ * Adds special treatment of arrays over and above the superclass.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class CacheMarshaller300 extends CacheMarshaller210
+{
+   @Override
+   protected void marshallObject(Object o, ObjectOutputStream out, Map<Object, Integer> refMap) throws Exception
+   {
+      if (o != null && o.getClass().isArray() && isKnownType(o.getClass().getComponentType()))
+      {
+         marshallArray(o, out, refMap);
+      }
+      else
+      {
+         super.marshallObject(o, out, refMap);
+      }
+   }
+
+   protected boolean isKnownType(Class c)
+   {
+      return (c.equals(Object.class) ||
+            c.isPrimitive() || c.equals(Character.class) || c.equals(Integer.class) || c.equals(Long.class) ||
+            c.equals(Byte.class) || c.equals(Boolean.class) || c.equals(Short.class) || c.equals(Float.class) ||
+            c.equals(Double.class));
+   }
+
+   protected void marshallArray(Object o, ObjectOutputStream out, Map<Object, Integer> refMap) throws Exception
+   {
+      out.writeByte(MAGICNUMBER_ARRAY);
+      Class arrayTypeClass = o.getClass().getComponentType();
+      int sz = Array.getLength(o);
+      writeUnsignedInt(out, sz);
+      boolean isPrim = arrayTypeClass.isPrimitive();
+
+      if (!isPrim && arrayTypeClass.equals(Object.class))
+      {
+         out.writeByte(MAGICNUMBER_OBJECT);
+         for (int i = 0; i < sz; i++) marshallObject(Array.get(o, i), out, refMap);
+      }
+      else if (arrayTypeClass.equals(byte.class) || arrayTypeClass.equals(Byte.class))
+      {
+         out.writeByte(MAGICNUMBER_BYTE);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            out.write((byte[]) o);
+         else
+            for (int i = 0; i < sz; i++) out.writeByte((Byte) Array.get(o, i));
+      }
+      else if (arrayTypeClass.equals(int.class) || arrayTypeClass.equals(Integer.class))
+      {
+         out.writeByte(MAGICNUMBER_INTEGER);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            for (int i = 0; i < sz; i++) out.writeInt(Array.getInt(o, i));
+         else
+            for (int i = 0; i < sz; i++) out.writeInt((Integer) Array.get(o, i));
+      }
+
+      else if (arrayTypeClass.equals(long.class) || arrayTypeClass.equals(Long.class))
+      {
+         out.writeByte(MAGICNUMBER_LONG);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            for (int i = 0; i < sz; i++) out.writeLong(Array.getLong(o, i));
+         else
+            for (int i = 0; i < sz; i++) out.writeLong((Long) Array.get(o, i));
+      }
+      else if (arrayTypeClass.equals(boolean.class) || arrayTypeClass.equals(Boolean.class))
+      {
+         out.writeByte(MAGICNUMBER_BOOLEAN);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            for (int i = 0; i < sz; i++) out.writeBoolean(Array.getBoolean(o, i));
+         else
+            for (int i = 0; i < sz; i++) out.writeBoolean((Boolean) Array.get(o, i));
+      }
+      else if (arrayTypeClass.equals(char.class) || arrayTypeClass.equals(Character.class))
+      {
+         out.writeByte(MAGICNUMBER_CHAR);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            for (int i = 0; i < sz; i++) out.writeChar(Array.getChar(o, i));
+         else
+            for (int i = 0; i < sz; i++) out.writeChar((Character) Array.get(o, i));
+      }
+      else if (arrayTypeClass.equals(short.class) || arrayTypeClass.equals(Short.class))
+      {
+         out.writeByte(MAGICNUMBER_SHORT);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            for (int i = 0; i < sz; i++) out.writeShort(Array.getShort(o, i));
+         else
+            for (int i = 0; i < sz; i++) out.writeShort((Short) Array.get(o, i));
+      }
+      else if (arrayTypeClass.equals(float.class) || arrayTypeClass.equals(Float.class))
+      {
+         out.writeByte(MAGICNUMBER_FLOAT);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            for (int i = 0; i < sz; i++) out.writeFloat(Array.getFloat(o, i));
+         else
+            for (int i = 0; i < sz; i++) out.writeFloat((Float) Array.get(o, i));
+      }
+      else if (arrayTypeClass.equals(double.class) || arrayTypeClass.equals(Double.class))
+      {
+         out.writeByte(MAGICNUMBER_DOUBLE);
+         out.writeBoolean(isPrim);
+         if (isPrim)
+            for (int i = 0; i < sz; i++) out.writeDouble(Array.getDouble(o, i));
+         else
+            for (int i = 0; i < sz; i++) out.writeDouble((Double) Array.get(o, i));
+      }
+      else throw new CacheException("Unknown array type!");
+   }
+}

Modified: core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java	2008-09-18 16:03:00 UTC (rev 6753)
+++ core/trunk/src/main/java/org/jboss/cache/marshall/VersionAwareMarshaller.java	2008-09-18 17:18:38 UTC (rev 6754)
@@ -283,19 +283,29 @@
             break;
          case VERSION_220:
          case VERSION_210:
+            marshaller = marshallers.get(VERSION_210);
+            if (marshaller == null)
+            {
+               am = new CacheMarshaller210();
+               marshaller = am;
+               componentRegistry.wireDependencies(am);
+               am.init();
+               marshallers.put(VERSION_210, marshaller);
+            }
+            break;
          case VERSION_300:
             knownVersion = true;
          default:
             if (!knownVersion && log.isWarnEnabled())
                log.warn("Unknown replication version [" + versionId + "].  Falling back to the default marshaller installed.");
-            marshaller = marshallers.get(VERSION_210);
+            marshaller = marshallers.get(VERSION_300);
             if (marshaller == null)
             {
-               am = new CacheMarshaller210();
+               am = new CacheMarshaller300();
                marshaller = am;
                componentRegistry.wireDependencies(am);
                am.init();
-               marshallers.put(VERSION_210, marshaller);
+               marshallers.put(VERSION_300, marshaller);
             }
             break;
       }

Added: core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller300Test.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller300Test.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshaller300Test.java	2008-09-18 17:18:38 UTC (rev 6754)
@@ -0,0 +1,89 @@
+package org.jboss.cache.marshall;
+
+import org.jboss.cache.Fqn;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+ at Test(groups = {"functional"})
+public class CacheMarshaller300Test
+{
+   public void testArrayTypes() throws Exception
+   {
+      Marshaller m = new CacheMarshaller300();
+      ByteArrayOutputStream bout = new ByteArrayOutputStream();
+      ObjectOutputStream out = new ObjectOutputStream(bout);
+      byte[] s = {1, 2, 3, 4};
+      m.objectToObjectStream(s, out);
+      out.close();
+
+      ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+      ObjectInputStream ois = new ObjectInputStream(bin);
+
+      Object o = m.objectFromObjectStream(ois);
+
+      ois.close();
+
+      assert o instanceof byte[];
+      byte[] oS = (byte[]) o;
+      assert oS.length == 4;
+      assert oS[0] == 1;
+      assert oS[1] == 2;
+      assert oS[2] == 3;
+      assert oS[3] == 4;
+   }
+
+   public void testBoxedArrayTypes() throws Exception
+   {
+      Marshaller m = new CacheMarshaller300();
+      ByteArrayOutputStream bout = new ByteArrayOutputStream();
+      ObjectOutputStream out = new ObjectOutputStream(bout);
+      Byte[] s = new Byte[]{1, 2, 3, 4};
+      m.objectToObjectStream(s, out);
+      out.close();
+
+      ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+      ObjectInputStream ois = new ObjectInputStream(bin);
+
+      Object o = m.objectFromObjectStream(ois);
+
+      ois.close();
+
+      assert o instanceof Byte[];
+      Byte[] oS = (Byte[]) o;
+      assert oS.length == 4;
+      assert oS[0] == 1;
+      assert oS[1] == 2;
+      assert oS[2] == 3;
+      assert oS[3] == 4;
+   }
+
+   public void testMixedArrayTypes() throws Exception
+   {
+      Marshaller m = new CacheMarshaller300();
+      ByteArrayOutputStream bout = new ByteArrayOutputStream();
+      ObjectOutputStream out = new ObjectOutputStream(bout);
+      Object[] s = {"Hello", Fqn.fromString("/a"), 1, null};
+      m.objectToObjectStream(s, out);
+      out.close();
+
+      ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+      ObjectInputStream ois = new ObjectInputStream(bin);
+
+      Object o = m.objectFromObjectStream(ois);
+
+      ois.close();
+
+      assert o instanceof Object[];
+      Object[] oS = (Object[]) o;
+      assert oS.length == 4;
+      assert oS[0].equals("Hello");
+      assert oS[1].equals(Fqn.fromString("/a"));
+      assert oS[2].equals(1);
+      assert oS[3] == null;
+
+   }
+}

Modified: core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java	2008-09-18 16:03:00 UTC (rev 6753)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/CacheMarshallerTestBase.java	2008-09-18 17:18:38 UTC (rev 6754)
@@ -29,7 +29,7 @@
 {
    protected String currentVersion;
    protected int currentVersionShort;
-   protected Class expectedMarshallerClass, latestMarshallerClass = CacheMarshaller210.class;
+   protected Class expectedMarshallerClass, latestMarshallerClass = CacheMarshaller300.class;
    protected VersionAwareMarshaller marshaller;
    protected RegionManager regionManager;
    protected Configuration c;
@@ -90,7 +90,7 @@
       assertEquals(CacheMarshaller200.class, marshaller.getMarshaller(20).getClass());
       assertEquals(CacheMarshaller210.class, marshaller.getMarshaller(21).getClass());
 
-      assert marshaller.marshallers.size() == 2 : "Should have 2 marshallers now";
+      assert marshaller.marshallers.size() == 3 : "Should have 3 marshallers now";
    }
 
    public void testStringBasedFqn() throws Exception

Modified: core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java	2008-09-18 16:03:00 UTC (rev 6753)
+++ core/trunk/src/test/java/org/jboss/cache/marshall/VersionAwareMarshallerTest.java	2008-09-18 17:18:38 UTC (rev 6754)
@@ -51,25 +51,25 @@
       assertEquals(CacheMarshaller200.class, marshaller.defaultMarshaller.getClass());
 
       marshaller = createVAMandRestartCache("1.4.0.GA");
-      assertEquals(CacheMarshaller210.class, marshaller.defaultMarshaller.getClass());
+      assertEquals(CacheMarshaller300.class, marshaller.defaultMarshaller.getClass());
 
       marshaller = createVAMandRestartCache("1.5.0.GA");
-      assertEquals(CacheMarshaller210.class, marshaller.defaultMarshaller.getClass());
+      assertEquals(CacheMarshaller300.class, marshaller.defaultMarshaller.getClass());
 
       marshaller = createVAMandRestartCache("1.3.0.GA");
-      assertEquals(CacheMarshaller210.class, marshaller.defaultMarshaller.getClass());
+      assertEquals(CacheMarshaller300.class, marshaller.defaultMarshaller.getClass());
 
       marshaller = createVAMandRestartCache("1.3.0.SP2");
-      assertEquals(CacheMarshaller210.class, marshaller.defaultMarshaller.getClass());
+      assertEquals(CacheMarshaller300.class, marshaller.defaultMarshaller.getClass());
 
       marshaller = createVAMandRestartCache("1.3.1.GA");
-      assertEquals(CacheMarshaller210.class, marshaller.defaultMarshaller.getClass());
+      assertEquals(CacheMarshaller300.class, marshaller.defaultMarshaller.getClass());
 
       marshaller = createVAMandRestartCache("1.2.4.SP2");
-      assertEquals(CacheMarshaller210.class, marshaller.defaultMarshaller.getClass());
+      assertEquals(CacheMarshaller300.class, marshaller.defaultMarshaller.getClass());
 
       marshaller = createVAMandRestartCache("1.2.3");
-      assertEquals(CacheMarshaller210.class, marshaller.defaultMarshaller.getClass());
+      assertEquals(CacheMarshaller300.class, marshaller.defaultMarshaller.getClass());
    }
 
    public void testVersionHeaderDefaultCurrent() throws Exception




More information about the jbosscache-commits mailing list