Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 236   Methods: 10
NCLOC: 162   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
VersionAwareMarshaller.java 60% 82.4% 100% 80%
coverage coverage
 1    /*
 2    * JBoss, Home of Professional Open Source
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    */
 7    package org.jboss.cache.marshall;
 8   
 9    import org.apache.commons.logging.Log;
 10    import org.apache.commons.logging.LogFactory;
 11    import org.jboss.cache.Fqn;
 12    import org.jboss.cache.RegionManager;
 13    import org.jboss.cache.config.Configuration;
 14   
 15    import java.io.ByteArrayOutputStream;
 16    import java.io.InputStream;
 17    import java.io.ObjectInputStream;
 18    import java.io.ObjectOutputStream;
 19    import java.util.HashMap;
 20    import java.util.Map;
 21    import java.util.StringTokenizer;
 22   
 23    /**
 24    * A delegate to various other marshallers like {@link org.jboss.cache.marshall.CacheMarshaller200}.
 25    * This delegating marshaller adds versioning information to the stream when marshalling objects and
 26    * is able to pick the appropriate marshaller to delegate to based on the versioning information when
 27    * unmarshalling objects.
 28    *
 29    * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 30    * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
 31    */
 32    public class VersionAwareMarshaller extends AbstractMarshaller
 33    {
 34   
 35    private static final Log log = LogFactory.getLog(VersionAwareMarshaller.class);
 36    private static final int VERSION_200 = 20;
 37   
 38    private RegionManager manager;
 39    private boolean defaultInactive, useRegionBasedMarshalling;
 40    AbstractMarshaller defaultMarshaller;
 41    Map<Integer, Marshaller> marshallers = new HashMap<Integer, Marshaller>();
 42    private int versionInt;
 43   
 44  1501 public VersionAwareMarshaller(RegionManager manager, boolean defaultInactive, boolean useRegionBasedMarshalling, String version)
 45    {
 46  1501 this.manager = manager;
 47  1501 this.defaultInactive = defaultInactive;
 48  1501 this.useRegionBasedMarshalling = useRegionBasedMarshalling;
 49   
 50    // "Rounds down" the replication version passed in to the MINOR version.
 51    // E.g., 1.4.1.SP3 -> 1.4.0
 52   
 53  1501 versionInt = toMinorVersionInt(version);
 54   
 55  1501 switch (versionInt)
 56    {
 57  1493 case VERSION_200:
 58  8 default:
 59  1501 defaultMarshaller = new CacheMarshaller200(manager, defaultInactive, useRegionBasedMarshalling);
 60  1501 marshallers.put(VERSION_200, defaultMarshaller);
 61  1501 break;
 62    }
 63   
 64  1501 if (log.isDebugEnabled())
 65    {
 66  0 log.debug("Initialised with version " + version + " and versionInt " + versionInt);
 67  0 log.debug("Using default marshaller " + defaultMarshaller.getClass());
 68    }
 69    }
 70   
 71  1472 public VersionAwareMarshaller(RegionManager regionManager, Configuration configuration)
 72    {
 73  1472 this(regionManager, configuration.isInactiveOnStartup(), configuration.isUseRegionBasedMarshalling(), configuration.getReplVersionString());
 74    }
 75   
 76    /**
 77    * Converts versions to known compatible version ids.
 78    * <p/>
 79    * Typical return values:
 80    * <p/>
 81    * < 1.4.0 = "1"
 82    * 1.4.x = "14"
 83    * 1.5.x = "15"
 84    * 2.0.x = "20"
 85    * 2.1.x = "21"
 86    * <p/>
 87    * etc.
 88    *
 89    * @param version
 90    * @return a version integer
 91    */
 92  1501 private int toMinorVersionInt(String version)
 93    {
 94  1501 try
 95    {
 96  1501 StringTokenizer strtok = new StringTokenizer(version, ".");
 97   
 98    // major, minor, micro, patch
 99  1501 String[] versionComponents = {null, null, null, null};
 100  1501 int i = 0;
 101  1501 while (strtok.hasMoreTokens())
 102    {
 103  4529 versionComponents[i++] = strtok.nextToken();
 104    }
 105   
 106  1501 int major = Integer.parseInt(versionComponents[0]);
 107  1501 int minor = Integer.parseInt(versionComponents[1]);
 108   
 109  1501 return (major > 1 || minor > 3) ? (10 * major) + minor : 1;
 110    }
 111    catch (Exception e)
 112    {
 113  0 throw new IllegalArgumentException("Unsupported replication version string " + version);
 114    }
 115    }
 116   
 117  342492 public byte[] objectToByteBuffer(Object obj) throws Exception
 118    {
 119  342488 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 120  342492 ObjectOutputStream out;
 121   
 122    // based on the default marshaller, construct an object output stream based on what's compatible.
 123  342492 out = ObjectSerializationFactory.createObjectOutputStream(bos);
 124  342492 out.writeShort(versionInt);
 125  0 if (log.isTraceEnabled()) log.trace("Wrote version " + versionInt);
 126   
 127    //now marshall the contents of the object
 128  342492 defaultMarshaller.objectToObjectStream(obj, out);
 129  342488 out.close();
 130   
 131    // and return bytes.
 132  342489 return bos.toByteArray();
 133    }
 134   
 135  327156 public Object objectFromByteBuffer(byte[] buf) throws Exception
 136    {
 137  327156 Marshaller marshaller;
 138  327156 int versionId;
 139  327156 ObjectInputStream in;
 140  327155 try
 141    {
 142  327156 in = ObjectSerializationFactory.createObjectInputStream(buf);
 143  327156 versionId = in.readShort();
 144  0 if (log.isTraceEnabled()) log.trace("Read version " + versionId);
 145    }
 146    catch (Exception e)
 147    {
 148  0 log.error("Unable to read version id from first two bytes of stream, barfing.");
 149  0 throw e;
 150    }
 151   
 152  327155 marshaller = getMarshaller(versionId);
 153   
 154  327156 return marshaller.objectFromObjectStream(in);
 155    }
 156   
 157  15683 public Object objectFromStream(InputStream is) throws Exception
 158    {
 159  15683 Marshaller marshaller;
 160  15683 int versionId;
 161  15683 ObjectInputStream in;
 162  15683 try
 163    {
 164  15683 in = ObjectSerializationFactory.createObjectInputStream(is);
 165  15683 versionId = in.readShort();
 166  0 if (log.isTraceEnabled()) log.trace("Read version " + versionId);
 167    }
 168    catch (Exception e)
 169    {
 170  0 log.error("Unable to read version id from first two bytes of stream, barfing.");
 171  0 throw e;
 172    }
 173   
 174  15683 marshaller = getMarshaller(versionId);
 175   
 176  15683 return marshaller.objectFromObjectStream(in);
 177    }
 178   
 179  843 public void objectToObjectStream(Object obj, ObjectOutputStream out, Fqn region) throws Exception
 180    {
 181  843 out.writeShort(versionInt);
 182  0 if (log.isTraceEnabled()) log.trace("Wrote version " + versionInt);
 183  843 defaultMarshaller.objectToObjectStream(obj, out, region);
 184    }
 185   
 186    /**
 187    * Lazily instantiates and loads the relevant marshaller for a given version.
 188    *
 189    * @param versionId
 190    * @return appropriate marshaller for the version requested.
 191    */
 192  367205 Marshaller getMarshaller(int versionId)
 193    {
 194  367205 Marshaller marshaller;
 195  367205 switch (versionId)
 196    {
 197  367200 case VERSION_200:
 198  5 default:
 199  367205 marshaller = marshallers.get(VERSION_200);
 200  367205 if (marshaller == null)
 201    {
 202  0 marshaller = new CacheMarshaller200(manager, defaultInactive, useRegionBasedMarshalling);
 203  0 marshallers.put(VERSION_200, marshaller);
 204    }
 205  367205 break;
 206    }
 207  367205 return marshaller;
 208    }
 209   
 210  20862 public void objectToObjectStream(Object obj, ObjectOutputStream out) throws Exception
 211    {
 212  20862 out.writeShort(versionInt);
 213  0 if (log.isTraceEnabled()) log.trace("Wrote version " + versionInt);
 214  20862 defaultMarshaller.objectToObjectStream(obj, out);
 215    }
 216   
 217  24365 public Object objectFromObjectStream(ObjectInputStream in) throws Exception
 218    {
 219  24365 Marshaller marshaller;
 220  24365 int versionId;
 221  24365 try
 222    {
 223  24365 versionId = in.readShort();
 224  0 if (log.isTraceEnabled()) log.trace("Read version " + versionId);
 225    }
 226    catch (Exception e)
 227    {
 228  4 log.error("Unable to read version id from first two bytes of stream, barfing.");
 229  4 throw e;
 230    }
 231   
 232  24361 marshaller = getMarshaller(versionId);
 233   
 234  24361 return marshaller.objectFromObjectStream(in);
 235    }
 236    }