Clover coverage report - Code Coverage for tapestry release 4.0-beta-6
Coverage timestamp: Wed Sep 7 2005 18:41:34 EDT
file stats: LOC: 237   Methods: 8
NCLOC: 111   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DataSqueezerImpl.java 85.3% 81.5% 75% 82.2%
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.util.Iterator;
 18    import java.util.List;
 19   
 20    import org.apache.hivemind.lib.util.StrategyRegistry;
 21    import org.apache.hivemind.lib.util.StrategyRegistryImpl;
 22    import org.apache.tapestry.Tapestry;
 23    import org.apache.tapestry.services.DataSqueezer;
 24   
 25    /**
 26    * A class used to convert arbitrary objects to Strings and back. This has particular uses involving
 27    * HTTP URLs and Cookies.
 28    *
 29    * @author Howard Lewis Ship
 30    */
 31   
 32    public class DataSqueezerImpl implements DataSqueezer
 33    {
 34    private static final String NULL_PREFIX = "X";
 35   
 36    private static final char NULL_PREFIX_CH = 'X';
 37   
 38    private static final int ARRAY_SIZE = 90;
 39   
 40    private static final int FIRST_ADAPTOR_OFFSET = 33;
 41   
 42    /**
 43    * An array of adaptors; this is used as a cheap lookup-table when unsqueezing. Each adaptor is
 44    * identified by a single ASCII character, in the range of 33 ('!') to 122 (the letter 'z'). The
 45    * offset into this table is the character minus 33.
 46    */
 47   
 48    private SqueezeAdaptor[] _adaptorByPrefix = new SqueezeAdaptor[ARRAY_SIZE];
 49   
 50    /**
 51    * AdaptorRegistry cache of adaptors.
 52    */
 53   
 54    private StrategyRegistry _adaptors = new StrategyRegistryImpl();
 55   
 56  9 public void setSqueezeAdaptors(List adaptors)
 57    {
 58  9 Iterator i = adaptors.iterator();
 59   
 60  9 while (i.hasNext())
 61    {
 62  99 SqueezeAdaptor adaptor = (SqueezeAdaptor) i.next();
 63  99 register(adaptor);
 64    }
 65    }
 66   
 67    /**
 68    * Registers the adaptor with one or more single-character prefixes.
 69    * <p>
 70    * <b>Note</b>: This method should be used for testing purposes only! Squeeze adaptors are
 71    * normally injected by HiveMind.
 72    *
 73    * @param adaptor
 74    * the adaptor which to be registered.
 75    */
 76   
 77  413 public synchronized void register(SqueezeAdaptor adaptor)
 78    {
 79  413 if (adaptor == null)
 80  1 throw new IllegalArgumentException(Tapestry.getMessage("DataSqueezer.null-adaptor"));
 81   
 82  412 String prefix = adaptor.getPrefix();
 83  412 int prefixLength = prefix.length();
 84  412 int offset;
 85   
 86  412 if (prefixLength < 1)
 87  1 throw new IllegalArgumentException(Tapestry.getMessage("DataSqueezer.short-prefix"));
 88   
 89  411 Class dataClass = adaptor.getDataClass();
 90  411 if (dataClass == null)
 91  1 throw new IllegalArgumentException(Tapestry.getMessage("DataSqueezer.null-class"));
 92   
 93  410 for (int i = 0; i < prefixLength; i++)
 94    {
 95  854 char ch = prefix.charAt(i);
 96   
 97  854 if (ch < '!' | ch > 'z')
 98  1 throw new IllegalArgumentException(Tapestry
 99    .getMessage("DataSqueezer.prefix-out-of-range"));
 100   
 101  853 offset = ch - FIRST_ADAPTOR_OFFSET;
 102   
 103  853 if (_adaptorByPrefix[offset] != null)
 104  1 throw new IllegalArgumentException(Tapestry.format(
 105    "DataSqueezer.adaptor-prefix-taken",
 106    prefix.substring(i, i)));
 107   
 108  852 _adaptorByPrefix[offset] = adaptor;
 109   
 110    }
 111   
 112  408 _adaptors.register(dataClass, adaptor);
 113    }
 114   
 115    /**
 116    * Squeezes the data object into a String by locating an appropriate adaptor that can perform
 117    * the conversion. data may be null.
 118    */
 119   
 120  152 public String squeeze(Object data)
 121    {
 122  152 SqueezeAdaptor adaptor;
 123   
 124  152 if (data == null)
 125  2 return NULL_PREFIX;
 126   
 127  150 adaptor = (SqueezeAdaptor) _adaptors.getStrategy(data.getClass());
 128   
 129  150 return adaptor.squeeze(this, data);
 130    }
 131   
 132    /**
 133    * A convience; invokes {@link #squeeze(Object)}for each element in the data array. If data is
 134    * null, returns null.
 135    */
 136   
 137  14 public String[] squeeze(Object[] data)
 138    {
 139  14 if (data == null)
 140  1 return null;
 141   
 142  13 int length = data.length;
 143  13 String[] result;
 144   
 145  13 result = new String[length];
 146   
 147  13 for (int i = 0; i < length; i++)
 148  34 result[i] = squeeze(data[i]);
 149   
 150  13 return result;
 151    }
 152   
 153    /**
 154    * Unsqueezes the string. Note that in a special case, where the first character of the string
 155    * is not a recognized prefix, it is assumed that the string is simply a string, and return with
 156    * no change.
 157    */
 158   
 159  83 public Object unsqueeze(String string)
 160    {
 161  83 SqueezeAdaptor adaptor = null;
 162   
 163  83 if (string.equals(NULL_PREFIX))
 164  2 return null;
 165   
 166  81 int offset = string.charAt(0) - FIRST_ADAPTOR_OFFSET;
 167   
 168  81 if (offset >= 0 && offset < _adaptorByPrefix.length)
 169  81 adaptor = _adaptorByPrefix[offset];
 170   
 171    // If the adaptor is not otherwise recognized, the it is simply
 172    // an encoded String (the StringAdaptor may not have added
 173    // a prefix).
 174   
 175  81 if (adaptor == null)
 176  2 return string;
 177   
 178    // Adaptor should never be null, because we always supply
 179    // an adaptor for String
 180   
 181  79 return adaptor.unsqueeze(this, string);
 182    }
 183   
 184    /**
 185    * Convienience method for unsqueezing many strings (back into objects).
 186    * <p>
 187    * If strings is null, returns null.
 188    */
 189   
 190  16 public Object[] unsqueeze(String[] strings)
 191    {
 192  16 if (strings == null)
 193  1 return null;
 194   
 195  15 int length = strings.length;
 196  15 Object[] result;
 197   
 198  15 result = new Object[length];
 199   
 200  15 for (int i = 0; i < length; i++)
 201  37 result[i] = unsqueeze(strings[i]);
 202   
 203  15 return result;
 204    }
 205   
 206    /**
 207    * Checks to see if a given prefix character has a registered adaptor. This is used by the
 208    * String adaptor to determine whether it needs to put a prefix on its String.
 209    */
 210   
 211  0 public boolean isPrefixRegistered(char prefix)
 212    {
 213  0 int offset = prefix - FIRST_ADAPTOR_OFFSET;
 214   
 215    // Special case for handling nulls.
 216   
 217  0 if (prefix == NULL_PREFIX_CH)
 218  0 return true;
 219   
 220  0 if (offset < 0 || offset >= _adaptorByPrefix.length)
 221  0 return false;
 222   
 223  0 return _adaptorByPrefix[offset] != null;
 224    }
 225   
 226  0 public String toString()
 227    {
 228  0 StringBuffer buffer;
 229   
 230  0 buffer = new StringBuffer();
 231  0 buffer.append("DataSqueezer[adaptors=<");
 232  0 buffer.append(_adaptors.toString());
 233  0 buffer.append(">]");
 234   
 235  0 return buffer.toString();
 236    }
 237    }