[jboss-cvs] JBossAS SVN: r72594 - in projects/cluster/ha-server-api/trunk/src: main/java/org/jboss/ha/framework/interfaces and 9 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Apr 22 22:27:45 EDT 2008


Author: bstansberry at jboss.com
Date: 2008-04-22 22:27:45 -0400 (Tue, 22 Apr 2008)
New Revision: 72594

Added:
   projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/interfaces/CachableMarshalledValue.java
   projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/MarshalledValueHelper.java
   projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/SimpleCachableMarshalledValue.java
   projects/cluster/ha-server-api/trunk/src/test/
   projects/cluster/ha-server-api/trunk/src/test/java/
   projects/cluster/ha-server-api/trunk/src/test/java/org/
   projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/
   projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/
   projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/ha/
   projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/ha/framework/
   projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/ha/framework/server/
   projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/ha/framework/server/SimpleCachableMarshalledValueUnitTestCase.java
Log:
[JBCLUSTER-197] CachableMarshalledValue

Added: projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/interfaces/CachableMarshalledValue.java
===================================================================
--- projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/interfaces/CachableMarshalledValue.java	                        (rev 0)
+++ projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/interfaces/CachableMarshalledValue.java	2008-04-23 02:27:45 UTC (rev 72594)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.ha.framework.interfaces;
+
+import java.io.IOException;
+
+import org.jboss.util.stream.IMarshalledValue;
+
+/**
+ * <code>IMarshalledValue</code> subinterface intended for implementations that
+ * intend to hold onto a ref to deserialized form of the object they wrap.
+ * 
+ * @author Brian Stansberry
+ */
+public interface CachableMarshalledValue extends IMarshalledValue
+{
+   /**
+    * Serialize any deserialized wrapped object to a byte[] and release any 
+    * references to the deserialized form.
+    * 
+    * @return the serialized form of the wrapped object, or <code>null</code>
+    *         if there was no wrapped object.
+    *         
+    * @throws IOException
+    */
+   byte[] toByteArray() throws IOException;
+}

Added: projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/MarshalledValueHelper.java
===================================================================
--- projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/MarshalledValueHelper.java	                        (rev 0)
+++ projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/MarshalledValueHelper.java	2008-04-23 02:27:45 UTC (rev 72594)
@@ -0,0 +1,25 @@
+package org.jboss.ha.framework.server;
+
+
+/**
+ * Utility related to use of a marshalled value.
+ *
+ * @author Brian Stansberry based on a class by Manik Surtani
+ */
+public class MarshalledValueHelper
+{
+   /**
+    * Tests whether the type should be excluded from MarshalledValue wrapping.
+    *
+    * @param type type to test.  Should not be null.
+    * @return true if it should be excluded from MarshalledValue wrapping.
+    */
+   public static boolean isTypeExcluded(Class type)
+   {
+      return type.equals(String.class) || type.isPrimitive() ||
+            type.equals(Void.class) || type.equals(Boolean.class) || type.equals(Character.class) ||
+            type.equals(Byte.class) || type.equals(Short.class) || type.equals(Integer.class) ||
+            type.equals(Long.class) || type.equals(Float.class) || type.equals(Double.class) ||
+            (type.isArray() && isTypeExcluded(type.getComponentType()));
+   }
+}

Added: projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/SimpleCachableMarshalledValue.java
===================================================================
--- projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/SimpleCachableMarshalledValue.java	                        (rev 0)
+++ projects/cluster/ha-server-api/trunk/src/main/java/org/jboss/ha/framework/server/SimpleCachableMarshalledValue.java	2008-04-23 02:27:45 UTC (rev 72594)
@@ -0,0 +1,265 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, 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.ha.framework.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.jboss.ha.framework.interfaces.CachableMarshalledValue;
+import org.jboss.util.stream.MarshalledValueInputStream;
+import org.jboss.util.stream.MarshalledValueOutputStream;
+
+/**
+ * Variation on the standard JBoss <code>org.jboss.invocation.MarshalledValue</code>
+ * that only converts the wrapped object to a serialized form during
+ * serialization itself. Allows the marshalled value to be cached without adding
+ * the memory overhead of maintaining a byte[] version of the wrapped object.
+ *
+ * @author Brian Stansberry
+ * @version $Revision: 37459 $
+ */
+public class SimpleCachableMarshalledValue
+   implements java.io.Externalizable, CachableMarshalledValue
+{
+   /**
+    * The serialized form of the value.
+    */
+   private byte[] serializedForm;
+   
+   /**
+    * The raw form of the passed in object.
+    */
+   private Serializable raw;
+   
+   private int hashCode;
+
+   /**
+    * Exposed for externalization.
+    */
+   public SimpleCachableMarshalledValue()
+   {
+      super();
+   }
+
+   public SimpleCachableMarshalledValue(Serializable obj)
+   {
+      this.raw = obj;
+      if (this.raw != null)
+      {
+         this.hashCode = raw.hashCode();
+      }
+   }
+
+   public synchronized Serializable get() throws IOException, ClassNotFoundException
+   {
+      if (raw == null)
+      {
+         if (serializedForm != null)
+         {
+            ByteArrayInputStream bais = new ByteArrayInputStream(serializedForm);
+            MarshalledValueInputStream mvis = new MarshalledValueInputStream(bais);
+            try
+            {
+               raw =  (Serializable) mvis.readObject();
+               serializedForm = null;
+            }
+            finally
+            {
+               mvis.close();
+            }
+         }         
+      }
+      return raw;
+   }
+
+   public synchronized byte[] toByteArray() throws IOException
+   {
+      if (serializedForm == null)
+      {
+         serializedForm = serialize();
+      }
+      
+      raw = null;
+      
+      return serializedForm;
+   }
+   
+   private byte[] serialize() throws IOException
+   {
+      byte[] result = serializedForm;
+      if (result == null)
+      {
+         if (raw != null)
+         {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            MarshalledValueOutputStream mvos = new MarshalledValueOutputStream(baos);
+            mvos.writeObject(raw);
+            mvos.flush();
+            try
+            {
+               result = baos.toByteArray();
+            }
+            finally
+            {
+               mvos.close();
+            }
+         }
+         
+      }
+      return result;
+   }
+   
+   public Serializable peekUnderlyingObject()
+   {
+      return raw;
+   }
+   
+   public byte[] peekSerializedForm()
+   {
+      return serializedForm;
+   }
+
+   /**
+    * Return a hash code for the wrapped object.
+    *
+    * @return the serialized form value hash.
+    */
+   @Override
+   public int hashCode()
+   {
+      return hashCode;
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if( this == obj )
+         return true;
+
+      boolean equals = false;
+      if( obj instanceof SimpleCachableMarshalledValue )
+      {
+         SimpleCachableMarshalledValue mv = (SimpleCachableMarshalledValue) obj;
+         if (raw != null && mv.raw != null)
+         {
+            equals = raw.equals(mv.raw);
+         }
+         else if (serializedForm != null && mv.serializedForm != null)
+         {
+            if( serializedForm == mv.serializedForm )
+            {
+               equals = true;
+            }
+            else
+            {
+               equals = Arrays.equals(serializedForm, mv.serializedForm);
+            }
+         }
+         else
+         {
+            byte[] us = null;
+            byte[] them = null;
+            try
+            {
+               us = serialize();
+               them = mv.serialize();
+               equals = Arrays.equals(us, them);
+            }
+            catch (IOException e)
+            {
+               throw new RuntimeException("Cannot serialize " + ((us == null && raw != null) ? "us" : "them"), e);
+            }
+         }
+      }
+      return equals;
+   }
+   
+   @Override
+   public String toString()
+   {
+      StringBuilder sb = new StringBuilder(getClass().getName());
+      sb.append("{raw=");
+      sb.append(raw == null ? "null" : raw);
+      sb.append("serialized=");
+      sb.append(serializedForm==null ? "false" : "true");
+      sb.append('}');
+      return sb.toString();
+   }
+   
+   /**
+    * The object implements the readExternal method to restore its
+    * contents by calling the methods of DataInput for primitive
+    * types and readObject for objects, strings and arrays.  The
+    * readExternal method must read the values in the same sequence
+    * and with the same types as were written by writeExternal.
+    *
+    * @param in the stream to read data from in order to restore the object
+    * 
+    * @throws IOException              if I/O errors occur
+    * @throws ClassNotFoundException   If the class for an object being
+    *                                  restored cannot be found.
+    */
+   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+   {
+      int length = in.readInt();
+      serializedForm = null;
+      if( length > 0 )
+      {
+         serializedForm = new byte[length];
+         in.readFully(serializedForm);
+      }
+      hashCode = in.readInt();
+   }
+
+   /**
+    * The object implements the writeExternal method to save its contents
+    * by calling the methods of DataOutput for its primitive values or
+    * calling the writeObject method of ObjectOutput for objects, strings,
+    * and arrays.
+    *
+    * @serialData Overriding methods should use this tag to describe
+    *            the data layout of this Externalizable object.
+    *            List the sequence of element types and, if possible,
+    *            relate the element to a public/protected field and/or
+    *            method of this Externalizable class.
+    *
+    * @param out    the stream to write the object to
+    * 
+    * @throws IOException   Includes any I/O exceptions that may occur
+    */
+   public synchronized void writeExternal(ObjectOutput out) throws IOException
+   {
+      byte[] bytes = serialize();
+      int length = bytes != null ? bytes.length : 0;
+      out.writeInt(length);
+      if( length > 0 )
+      {
+         out.write(bytes);
+      }
+      out.writeInt(hashCode);
+   }
+}

Added: projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/ha/framework/server/SimpleCachableMarshalledValueUnitTestCase.java
===================================================================
--- projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/ha/framework/server/SimpleCachableMarshalledValueUnitTestCase.java	                        (rev 0)
+++ projects/cluster/ha-server-api/trunk/src/test/java/org/jboss/test/ha/framework/server/SimpleCachableMarshalledValueUnitTestCase.java	2008-04-23 02:27:45 UTC (rev 72594)
@@ -0,0 +1,214 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.test.ha.framework.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.jboss.ha.framework.server.SimpleCachableMarshalledValue;
+import org.jboss.util.id.GUID;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for SimpleCachableMarshalledValue.
+ * 
+ * @author Brian Stansberry
+ */
+public class SimpleCachableMarshalledValueUnitTestCase extends TestCase
+{
+
+   /**
+    * Create a new SimpleCachableMarshalledValueUnitTestCase.
+    * 
+    * @param name
+    */
+   public SimpleCachableMarshalledValueUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testReplication() throws Exception
+   {
+      GUID guid = new GUID();
+      SimpleCachableMarshalledValue mv = new SimpleCachableMarshalledValue(guid);
+      
+      SimpleCachableMarshalledValue copy = replicate(mv);
+      assertNull(copy.peekUnderlyingObject());
+      byte[] serialized = copy.peekSerializedForm();
+      assertNotNull(serialized);
+      
+      assertNull(mv.peekSerializedForm());
+      assertSame(guid, mv.peekUnderlyingObject());
+      
+      Object guid2 =  unmarshall(serialized);
+      assertNotSame(guid, guid2);
+      assertEquals(guid, guid2);
+   }
+
+   /**
+    * Test method for {@link org.jboss.ha.framework.server.SimpleCachableMarshalledValue#get()}.
+    */
+   public void testGet() throws Exception
+   {
+      GUID guid = new GUID();
+      SimpleCachableMarshalledValue mv = new SimpleCachableMarshalledValue(guid);
+      
+      assertSame(guid, mv.get());
+      
+      SimpleCachableMarshalledValue copy = replicate(mv);
+      
+      Object guid2 =  copy.get();
+      assertNotSame(guid, guid2);
+      assertEquals(guid, guid2);
+      
+      copy.toByteArray();
+      SimpleCachableMarshalledValue triplet = replicate(copy);
+      guid2 = triplet.get();
+      assertEquals(guid, guid2);
+      
+      mv = new SimpleCachableMarshalledValue(null);
+      assertNull(mv.get());
+   }
+
+   /**
+    * Test method for {@link org.jboss.ha.framework.server.SimpleCachableMarshalledValue#toByteArray()}.
+    */
+   public void testToByteArray() throws Exception
+   {
+      GUID guid = new GUID();
+      SimpleCachableMarshalledValue mv = new SimpleCachableMarshalledValue(guid);
+      
+      assertNull(mv.peekSerializedForm());
+      
+      byte[] bytes = mv.toByteArray();
+      
+      assertNull(mv.peekUnderlyingObject());
+      
+      assertSame(bytes, mv.peekSerializedForm());
+      
+      byte[] bytes2 = mv.toByteArray();
+      
+      assertSame(bytes, bytes2); 
+      
+      SimpleCachableMarshalledValue copy = replicate(mv);
+      assertEquals(copy.peekSerializedForm(), copy.toByteArray());
+      
+      mv = new SimpleCachableMarshalledValue(null);
+      assertNull(mv.toByteArray());
+   }
+
+   /**
+    * Test method for {@link org.jboss.ha.framework.server.SimpleCachableMarshalledValue#equals(java.lang.Object)}.
+    */
+   public void testEquals() throws Exception
+   {
+      GUID guid = new GUID();
+      SimpleCachableMarshalledValue mv = new SimpleCachableMarshalledValue(guid);
+      
+      assertTrue(mv.equals(mv));
+      assertFalse(mv.equals(null));
+      
+      SimpleCachableMarshalledValue dup = new SimpleCachableMarshalledValue(guid);
+      assertTrue(mv.equals(dup));
+      assertTrue(dup.equals(mv));
+      
+      SimpleCachableMarshalledValue replica = replicate(mv);
+      assertTrue(mv.equals(replica));
+      assertTrue(replica.equals(mv));
+      
+      SimpleCachableMarshalledValue nulled = new SimpleCachableMarshalledValue(null);
+      assertFalse(mv.equals(nulled));
+      assertFalse(nulled.equals(mv));
+      assertFalse(replica.equals(nulled));
+      assertFalse(nulled.equals(replica));
+      assertTrue(nulled.equals(nulled));
+      assertFalse(nulled.equals(null));
+      assertTrue(nulled.equals(new SimpleCachableMarshalledValue(null)));
+   }
+
+   /**
+    * Test method for {@link org.jboss.ha.framework.server.SimpleCachableMarshalledValue#hashCode()}.
+    */
+   public void testHashCode() throws Exception
+   {
+      GUID guid = new GUID();
+      SimpleCachableMarshalledValue mv = new SimpleCachableMarshalledValue(guid);
+      assertEquals(guid.hashCode(), mv.hashCode());
+      
+      SimpleCachableMarshalledValue copy = replicate(mv);
+      assertEquals(guid.hashCode(), copy.hashCode());
+      
+      mv = new SimpleCachableMarshalledValue(null);
+      assertEquals(0, mv.hashCode());
+   }
+
+   /**
+    * Test method for {@link java.lang.Object#toString()}.
+    */
+   public void testToString() throws Exception
+   {
+      GUID guid = new GUID();
+      SimpleCachableMarshalledValue mv = new SimpleCachableMarshalledValue(guid);
+      assertNotNull(mv.toString());
+      
+      SimpleCachableMarshalledValue copy = replicate(mv);
+      assertNotNull(copy.toString());
+      
+      mv = new SimpleCachableMarshalledValue(null);
+      assertNotNull(mv.toString());
+   }
+
+   private SimpleCachableMarshalledValue replicate(SimpleCachableMarshalledValue mv) 
+      throws IOException, ClassNotFoundException
+   {
+      return (SimpleCachableMarshalledValue) unmarshall(marshall(mv));
+   }
+   
+   private byte[] marshall(SimpleCachableMarshalledValue mv) throws IOException
+   {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      ObjectOutputStream oos = new ObjectOutputStream(baos);
+      oos.writeObject(mv);
+      oos.close();
+      return baos.toByteArray();
+   }
+   
+   private Object unmarshall(byte[] bytes) 
+      throws IOException, ClassNotFoundException
+   {
+      ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+      ObjectInputStream ois = new ObjectInputStream(bais);
+      try
+      {
+         return ois.readObject();
+      }
+      finally
+      {
+         ois.close();
+      }
+   }
+}




More information about the jboss-cvs-commits mailing list