Clover coverage report - Code Coverage for tapestry release 4.0-alpha-3
Coverage timestamp: Mon May 16 2005 09:05:49 EDT
file stats: LOC: 188   Methods: 7
NCLOC: 102   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
ValueConverterImpl.java 90.9% 96% 100% 94.9%
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.coerce;
 16   
 
 17   
 import java.beans.PropertyEditor;
 18   
 import java.beans.PropertyEditorManager;
 19   
 import java.util.HashMap;
 20   
 import java.util.Iterator;
 21   
 import java.util.List;
 22   
 import java.util.Map;
 23   
 
 24   
 import org.apache.hivemind.ApplicationRuntimeException;
 25   
 import org.apache.hivemind.util.ConstructorUtils;
 26   
 import org.apache.hivemind.util.Defense;
 27   
 
 28   
 /**
 29   
  * Implementation of {@link org.apache.tapestry.coerce.ValueConverter}. Selects an appropriate type
 30   
  * converter and delegates to it.
 31   
  * 
 32   
  * @author Howard M. Lewis Ship
 33   
  * @since 4.0
 34   
  */
 35   
 public class ValueConverterImpl implements ValueConverter
 36   
 {
 37   
     private Map _converterMap = new HashMap();
 38   
 
 39   
     /** List of {@link org.apache.tapestry.coerce.TypeConverterContribution}. */
 40   
 
 41   
     public List _contributions;
 42   
 
 43   
     private Map _primitiveToWrapper = new HashMap();
 44   
 
 45   
     private Map _wrapperToPrimitive = new HashMap();
 46   
 
 47   
     {
 48  57
         store(boolean.class, Boolean.class);
 49  57
         store(byte.class, Byte.class);
 50  57
         store(short.class, Short.class);
 51  57
         store(char.class, Character.class);
 52  57
         store(int.class, Integer.class);
 53  57
         store(long.class, Long.class);
 54  57
         store(float.class, Float.class);
 55  57
         store(double.class, Double.class);
 56   
     }
 57   
 
 58  456
     private void store(Class primitive, Class wrapper)
 59   
     {
 60  456
         _primitiveToWrapper.put(primitive, wrapper);
 61   
 
 62  456
         _wrapperToPrimitive.put(wrapper, primitive);
 63   
     }
 64   
 
 65  48
     public void initializeService()
 66   
     {
 67  48
         Iterator i = _contributions.iterator();
 68  48
         while (i.hasNext())
 69   
         {
 70  138
             TypeConverterContribution c = (TypeConverterContribution) i.next();
 71   
 
 72  138
             _converterMap.put(c.getSubjectClass(), c.getConverter());
 73   
         }
 74   
     }
 75   
 
 76  3083
     public Object coerceValue(Object value, Class desiredType)
 77   
     {
 78  3083
         Defense.notNull(desiredType, "desiredType");
 79   
 
 80  3083
         Class effectiveType = convertType(desiredType);
 81   
 
 82   
         // Already the correct type? Go no further!
 83   
 
 84  3083
         if (value != null && effectiveType.isAssignableFrom(value.getClass()))
 85  2803
             return value;
 86   
         
 87  280
         Object result = convertNumberToNumber(value, effectiveType);
 88   
 
 89  280
         if (result != null)
 90  1
             return result;
 91   
 
 92  279
         result = convertUsingPropertyEditor(value, effectiveType);
 93   
 
 94  278
         if (result != null)
 95  14
             return result;
 96   
 
 97  264
         TypeConverter converter = (TypeConverter) _converterMap.get(effectiveType);
 98   
 
 99   
         // null value and no converter for the given type? Just return null.
 100   
 
 101  264
         if (value == null && converter == null)
 102  8
             return null;
 103   
 
 104  256
         if (converter == null)
 105  2
             throw new ApplicationRuntimeException(CoerceMessages.noConverter(effectiveType));
 106   
 
 107  254
         return converter.convertValue(value);
 108   
     }
 109   
 
 110   
     /**
 111   
      * Attempts to use {@link java.beans.PropertyEditor}to perform a conversion from a string to a
 112   
      * numeric type. Returns null if no property editor can be found.
 113   
      * 
 114   
      * @param value
 115   
      *            The value to convert
 116   
      * @param targetType
 117   
      *            The type to convert to (must be a wrapper type, not a primitive type)
 118   
      */
 119   
 
 120  279
     private Number convertUsingPropertyEditor(Object value, Class targetType)
 121   
     {
 122   
         // Convert from wrapper type back to primitive type, because
 123   
         // PropertyEditorManager expects primitive types not
 124   
         // wrapper types.
 125   
 
 126  279
         if (value == null || value.getClass() != String.class
 127   
                 || !Number.class.isAssignableFrom(targetType))
 128  264
             return null;
 129   
 
 130  15
         Class primitiveType = (Class) _wrapperToPrimitive.get(targetType);
 131   
 
 132   
         // Note a primitive type.
 133   
 
 134  15
         if (primitiveType == null)
 135  0
             return null;
 136   
 
 137   
         // Looks like a conversion from String to Number, let's see.
 138   
 
 139  15
         PropertyEditor editor = PropertyEditorManager.findEditor(primitiveType);
 140   
 
 141   
         // This should not happen, since we've filtered down to just the
 142   
         // primitive types that do have property editors.
 143   
 
 144  15
         if (editor == null)
 145  0
             return null;
 146   
 
 147  15
         String text = (String) value;
 148   
 
 149  15
         try
 150   
         {
 151  15
             editor.setAsText(text);
 152   
 
 153  14
             return (Number) editor.getValue();
 154   
         }
 155   
         catch (Exception ex)
 156   
         {
 157  1
             throw new ApplicationRuntimeException(CoerceMessages.stringToNumberConversionError(
 158   
                     text,
 159   
                     targetType,
 160   
                     ex), ex);
 161   
         }
 162   
 
 163   
     }
 164   
 
 165  280
     private Number convertNumberToNumber(Object value, Class targetType)
 166   
     {
 167  280
         if (value == null || !Number.class.isAssignableFrom(value.getClass())
 168   
                 || !Number.class.isAssignableFrom(targetType))
 169  279
             return null;
 170   
 
 171  1
         String valueAsString = value.toString();
 172   
 
 173  1
         return (Number) ConstructorUtils.invokeConstructor(targetType, new Object[]
 174   
         { valueAsString });
 175   
     }
 176   
 
 177  3083
     private Class convertType(Class possiblePrimitiveType)
 178   
     {
 179  3083
         Class wrapperType = (Class) _primitiveToWrapper.get(possiblePrimitiveType);
 180   
 
 181  3083
         return wrapperType == null ? possiblePrimitiveType : wrapperType;
 182   
     }
 183   
 
 184  48
     public void setContributions(List contributions)
 185   
     {
 186  48
         _contributions = contributions;
 187   
     }
 188   
 }