Clover coverage report - Code Coverage for tapestry release 4.0-beta-12
Coverage timestamp: Sun Oct 30 2005 16:22:01 EST
file stats: LOC: 215   Methods: 7
NCLOC: 101   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DataSqueezerImpl.java 96.7% 89.8% 85.7% 91.7%
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 int ARRAY_SIZE = 90;
 37   
 38    private static final int FIRST_ADAPTOR_OFFSET = 33;
 39   
 40    /**
 41    * An array of adaptors; this is used as a cheap lookup-table when unsqueezing. Each adaptor is
 42    * identified by a single ASCII character, in the range of 33 ('!') to 122 (the letter 'z'). The
 43    * offset into this table is the character minus 33.
 44    */
 45   
 46    private SqueezeAdaptor[] _adaptorByPrefix = new SqueezeAdaptor[ARRAY_SIZE];
 47   
 48    /**
 49    * AdaptorRegistry cache of adaptors.
 50    */
 51   
 52    private StrategyRegistry _adaptors = new StrategyRegistryImpl();
 53   
 54  9 public void setSqueezeAdaptors(List adaptors)
 55    {
 56  9 Iterator i = adaptors.iterator();
 57   
 58  9 while (i.hasNext())
 59    {
 60  99 SqueezeAdaptor adaptor = (SqueezeAdaptor) i.next();
 61  99 register(adaptor);
 62    }
 63    }
 64   
 65    /**
 66    * Registers the adaptor with one or more single-character prefixes.
 67    * <p>
 68    * <b>Note</b>: This method should be used for testing purposes only! Squeeze adaptors are
 69    * normally injected by HiveMind.
 70    *
 71    * @param adaptor
 72    * the adaptor which to be registered.
 73    */
 74   
 75  415 public synchronized void register(SqueezeAdaptor adaptor)
 76    {
 77  415 if (adaptor == null)
 78  1 throw new IllegalArgumentException(Tapestry.getMessage("DataSqueezer.null-adaptor"));
 79   
 80  414 String prefix = adaptor.getPrefix();
 81  414 int prefixLength = prefix.length();
 82  414 int offset;
 83   
 84  414 if (prefixLength < 1)
 85  1 throw new IllegalArgumentException(Tapestry.getMessage("DataSqueezer.short-prefix"));
 86   
 87  413 Class dataClass = adaptor.getDataClass();
 88  413 if (dataClass == null)
 89  1 throw new IllegalArgumentException(Tapestry.getMessage("DataSqueezer.null-class"));
 90   
 91  412 for (int i = 0; i < prefixLength; i++)
 92    {
 93  858 char ch = prefix.charAt(i);
 94   
 95  858 if (ch < '!' | ch > 'z')
 96  1 throw new IllegalArgumentException(Tapestry
 97    .getMessage("DataSqueezer.prefix-out-of-range"));
 98   
 99  857 offset = ch - FIRST_ADAPTOR_OFFSET;
 100   
 101  857 if (_adaptorByPrefix[offset] != null)
 102  1 throw new IllegalArgumentException(Tapestry.format(
 103    "DataSqueezer.adaptor-prefix-taken",
 104    prefix.substring(i, i)));
 105   
 106  856 _adaptorByPrefix[offset] = adaptor;
 107   
 108    }
 109   
 110  410 _adaptors.register(dataClass, adaptor);
 111    }
 112   
 113    /**
 114    * Squeezes the data object into a String by locating an appropriate adaptor that can perform
 115    * the conversion. data may be null.
 116    */
 117   
 118  153 public String squeeze(Object data)
 119    {
 120  153 SqueezeAdaptor adaptor;
 121   
 122  153 if (data == null)
 123  2 return NULL_PREFIX;
 124   
 125  151 adaptor = (SqueezeAdaptor) _adaptors.getStrategy(data.getClass());
 126   
 127  151 return adaptor.squeeze(this, data);
 128    }
 129   
 130    /**
 131    * A convience; invokes {@link #squeeze(Object)}for each element in the data array. If data is
 132    * null, returns null.
 133    */
 134   
 135  14 public String[] squeeze(Object[] data)
 136    {
 137  14 if (data == null)
 138  1 return null;
 139   
 140  13 int length = data.length;
 141  13 String[] result;
 142   
 143  13 result = new String[length];
 144   
 145  13 for (int i = 0; i < length; i++)
 146  34 result[i] = squeeze(data[i]);
 147   
 148  13 return result;
 149    }
 150   
 151    /**
 152    * Unsqueezes the string. Note that in a special case, where the first character of the string
 153    * is not a recognized prefix, it is assumed that the string is simply a string, and return with
 154    * no change.
 155    */
 156   
 157  84 public Object unsqueeze(String string)
 158    {
 159  84 SqueezeAdaptor adaptor = null;
 160   
 161  84 if (string.equals(NULL_PREFIX))
 162  2 return null;
 163   
 164  82 int offset = string.charAt(0) - FIRST_ADAPTOR_OFFSET;
 165   
 166  82 if (offset >= 0 && offset < _adaptorByPrefix.length)
 167  82 adaptor = _adaptorByPrefix[offset];
 168   
 169    // If the adaptor is not otherwise recognized, the it is simply
 170    // an encoded String (the StringAdaptor may not have added
 171    // a prefix).
 172   
 173  82 if (adaptor == null)
 174  2 return string;
 175   
 176    // Adaptor should never be null, because we always supply
 177    // an adaptor for String
 178   
 179  80 return adaptor.unsqueeze(this, string);
 180    }
 181   
 182    /**
 183    * Convienience method for unsqueezing many strings (back into objects).
 184    * <p>
 185    * If strings is null, returns null.
 186    */
 187   
 188  16 public Object[] unsqueeze(String[] strings)
 189    {
 190  16 if (strings == null)
 191  1 return null;
 192   
 193  15 int length = strings.length;
 194  15 Object[] result;
 195   
 196  15 result = new Object[length];
 197   
 198  15 for (int i = 0; i < length; i++)
 199  37 result[i] = unsqueeze(strings[i]);
 200   
 201  15 return result;
 202    }
 203   
 204  0 public String toString()
 205    {
 206  0 StringBuffer buffer;
 207   
 208  0 buffer = new StringBuffer();
 209  0 buffer.append("DataSqueezer[adaptors=<");
 210  0 buffer.append(_adaptors.toString());
 211  0 buffer.append(">]");
 212   
 213  0 return buffer.toString();
 214    }
 215    }