Clover coverage report - Code Coverage for tapestry release 4.0-beta-8
Coverage timestamp: Sat Sep 24 2005 11:50:34 EDT
file stats: LOC: 142   Methods: 5
NCLOC: 77   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
SerializableAdaptor.java 100% 93.3% 100% 95.1%
coverage coverage
 1    // Copyright 2004, 2005 The Apache Software Foundation
 2    //
 3    // Licensed under the Apache License, Version 2.0 (the "License");
 4    // you may not use this file except in compliance with the License.
 5    // You may obtain a copy of the License at
 6    //
 7    // http://www.apache.org/licenses/LICENSE-2.0
 8    //
 9    // Unless required by applicable law or agreed to in writing, software
 10    // distributed under the License is distributed on an "AS IS" BASIS,
 11    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    // See the License for the specific language governing permissions and
 13    // limitations under the License.
 14   
 15    package org.apache.tapestry.util.io;
 16   
 17    import java.io.BufferedInputStream;
 18    import java.io.BufferedOutputStream;
 19    import java.io.ByteArrayInputStream;
 20    import java.io.ByteArrayOutputStream;
 21    import java.io.InputStream;
 22    import java.io.ObjectInputStream;
 23    import java.io.ObjectOutputStream;
 24    import java.io.Serializable;
 25    import java.util.zip.GZIPInputStream;
 26    import java.util.zip.GZIPOutputStream;
 27   
 28    import org.apache.commons.codec.binary.Base64;
 29    import org.apache.hivemind.ApplicationRuntimeException;
 30    import org.apache.hivemind.ClassResolver;
 31    import org.apache.tapestry.services.DataSqueezer;
 32   
 33    /**
 34    * The most complicated of the adaptors, this one takes an arbitrary serializable object, serializes
 35    * it to binary (possibly encoding it), and encodes it in a Base64 encoding.
 36    * <p>
 37    * Encoding and decoding of Base64 strings uses code adapted from work in the public domain
 38    * originally written by Jonathan Knudsen and published in O'reilly's "Java Cryptography". Note that
 39    * we use a <em>modified</em> form of Base64 encoding, with URL-safe characters to encode the 62
 40    * and 63 values and the pad character.
 41    * <p>
 42    * TBD: Work out some class loader issues involved in deserializing.
 43    *
 44    * @author Howard Lewis Ship
 45    */
 46   
 47    public class SerializableAdaptor implements SqueezeAdaptor
 48    {
 49    private ClassResolver _resolver;
 50   
 51    private static final char BYTESTREAM_PREFIX = 'O';
 52   
 53    private static final char GZIP_BYTESTREAM_PREFIX = 'Z';
 54   
 55    // O is for an object stream rendered as MIME
 56    // Z is for on object stream, compressed, rendered as MIME
 57   
 58    private static final String PREFIX = "OZ";
 59   
 60  37 public String getPrefix()
 61    {
 62  37 return PREFIX;
 63    }
 64   
 65  37 public Class getDataClass()
 66    {
 67  37 return Serializable.class;
 68    }
 69   
 70  17 public String squeeze(DataSqueezer squeezer, Object data)
 71    {
 72  17 try
 73    {
 74  17 ByteArrayOutputStream bosPlain = new ByteArrayOutputStream();
 75  17 ByteArrayOutputStream bosCompressed = new ByteArrayOutputStream();
 76   
 77  17 GZIPOutputStream gos = new GZIPOutputStream(bosCompressed);
 78   
 79  17 TeeOutputStream tos = new TeeOutputStream(bosPlain, gos);
 80   
 81  17 ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(tos));
 82   
 83  17 oos.writeObject(data);
 84   
 85  17 oos.close();
 86   
 87  17 boolean useCompressed = bosCompressed.size() < bosPlain.size();
 88   
 89  17 byte[] byteArray = useCompressed ? bosCompressed.toByteArray() : bosPlain.toByteArray();
 90   
 91  17 byte[] encoded = Base64.encodeBase64(byteArray);
 92   
 93  17 String prefix = Character.toString(useCompressed ? GZIP_BYTESTREAM_PREFIX
 94    : BYTESTREAM_PREFIX);
 95   
 96  17 return prefix + new String(encoded);
 97    }
 98    catch (Exception ex)
 99    {
 100  0 throw new ApplicationRuntimeException(IoMessages.encodeFailure(data, ex), ex);
 101    }
 102    }
 103   
 104  5 public Object unsqueeze(DataSqueezer squeezer, String encoded)
 105    {
 106  5 char prefix = encoded.charAt(0);
 107   
 108  5 try
 109    {
 110    // Strip off the prefix, feed that in as a MIME stream.
 111   
 112  5 byte[] mimeData = encoded.substring(1).getBytes();
 113   
 114  5 byte[] decoded = Base64.decodeBase64(mimeData);
 115   
 116  5 InputStream is = new ByteArrayInputStream(decoded);
 117   
 118  5 if (prefix == GZIP_BYTESTREAM_PREFIX)
 119  1 is = new GZIPInputStream(is);
 120   
 121  5 is = new BufferedInputStream(is);
 122   
 123  5 ObjectInputStream ois = new ResolvingObjectInputStream(_resolver, is);
 124   
 125  5 Object result = ois.readObject();
 126   
 127  5 ois.close();
 128   
 129  5 return result;
 130    }
 131    catch (Exception ex)
 132    {
 133  0 throw new ApplicationRuntimeException(IoMessages.decodeFailure(ex), ex);
 134    }
 135    }
 136   
 137  37 public void setResolver(ClassResolver resolver)
 138    {
 139  37 _resolver = resolver;
 140    }
 141   
 142    }