Clover coverage report - Convert - proto0
Coverage timestamp: Mo Nov 22 2004 13:19:16 CET
file stats: LOC: 179   Methods: 7
NCLOC: 125   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
JlConverterFactory.java 100% 100% 100% 100%
coverage
 1    /*
 2    * Copyright 2004 Ronald Blaschke.
 3    *
 4    * Licensed under the Apache License, Version 2.0 (the "License");
 5    * you may not use this file except in compliance with the License.
 6    * You may obtain a copy of the License at
 7    *
 8    * http://www.apache.org/licenses/LICENSE-2.0
 9    *
 10    * Unless required by applicable law or agreed to in writing, software
 11    * distributed under the License is distributed on an "AS IS" BASIS,
 12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13    * See the License for the specific language governing permissions and
 14    * limitations under the License.
 15    */
 16    package org.rblasch.convert.converters.lang;
 17   
 18    import org.rblasch.convert.converters.AbstractConverterFactory;
 19    import org.rblasch.convert.converters.OnceConverterFactory;
 20    import org.rblasch.convert.converters.primitives.ByteToShortConverter;
 21    import org.rblasch.convert.converters.primitives.FloatToDoubleConverter;
 22    import org.rblasch.convert.converters.primitives.IntegerToLongConverter;
 23    import org.rblasch.convert.converters.primitives.ShortToIntegerConverter;
 24    import org.rblasch.convert.type.ClassType;
 25    import org.rblasch.convert.type.ParameterizableType;
 26    import org.rblasch.convert.type.Type;
 27    import org.rblasch.convert.type.Types;
 28   
 29    import java.util.ArrayList;
 30    import java.util.Arrays;
 31    import java.util.HashSet;
 32    import java.util.Iterator;
 33    import java.util.LinkedList;
 34    import java.util.List;
 35    import java.util.Set;
 36   
 37    /**
 38    * @author Ronald Blaschke
 39    */
 40    public class JlConverterFactory extends AbstractConverterFactory implements OnceConverterFactory {
 41  8 public Set/*<MetaConverter>*/ createOnce() {
 42  8 final Set/*<MetaConverter>*/ converters = new HashSet();
 43   
 44    // autoboxing
 45  8 converters.add(new CastConverter(Types.findTypeByName("byte"),
 46    Types.findTypeByClass(Byte.class)));
 47  8 converters.add(new CastConverter(Types.findTypeByClass(Byte.class),
 48    Types.findTypeByName("byte")));
 49  8 converters.add(new CastConverter(Types.findTypeByName("short"),
 50    Types.findTypeByClass(Short.class)));
 51  8 converters.add(new CastConverter(Types.findTypeByClass(Short.class),
 52    Types.findTypeByName("short")));
 53  8 converters.add(new CastConverter(Types.findTypeByName("int"),
 54    Types.findTypeByClass(Integer.class)));
 55  8 converters.add(new CastConverter(Types.findTypeByClass(Integer.class),
 56    Types.findTypeByName("int")));
 57  8 converters.add(new CastConverter(Types.findTypeByName("long"),
 58    Types.findTypeByClass(Long.class)));
 59  8 converters.add(new CastConverter(Types.findTypeByClass(Long.class),
 60    Types.findTypeByName("long")));
 61   
 62    // "default" number widening
 63  8 converters.add(new ByteToShortConverter());
 64  8 converters.add(new ShortToIntegerConverter());
 65  8 converters.add(new IntegerToLongConverter());
 66   
 67  8 converters.add(new FloatToDoubleConverter());
 68   
 69    // "default" .toString() conversion
 70  8 converters.add(new ObjectToStringConverter());
 71   
 72  8 return converters;
 73    }
 74   
 75    // cache already resolved types
 76    private final Set/*<Type>*/ resolvedTypes = new HashSet();
 77   
 78  7695 public Set/*<MetaConverter>*/ create(final Type sourceType, final Type destinationType) {
 79  7695 final Set/*<MetaConverter>*/ converters = new HashSet();
 80  7695 if (!resolvedTypes.contains(sourceType)) {
 81  9 converters.addAll(jlConverters(sourceType));
 82  9 resolvedTypes.add(sourceType);
 83    }
 84   
 85  7695 if (!resolvedTypes.contains(destinationType)) {
 86  85 converters.addAll(jlConverters(destinationType));
 87  85 resolvedTypes.add(destinationType);
 88    }
 89   
 90  7695 return converters;
 91    }
 92   
 93  114 private Set/*<MetaConverter>*/ jlConverters(final Type t) {
 94  114 final Set/*<MetaConverter>*/ converters = new HashSet();
 95   
 96  114 converters.add(new IdentityConverter(t));
 97   
 98    // class lookup
 99  114 if (t instanceof ClassType) {
 100  64 converters.addAll(castConverters(t));
 101  50 } else if (t instanceof ParameterizableType) {
 102  20 converters.addAll(castConverters(t));
 103   
 104    // recurse into all parameters
 105  20 final ParameterizableType pt = (ParameterizableType) t;
 106  20 for (final Iterator i = pt.getParameters().iterator(); i.hasNext();) {
 107  20 converters.addAll(jlConverters((Type) i.next()));
 108    }
 109    }
 110   
 111  114 return converters;
 112    }
 113   
 114  84 private Set/*<MetaConverter>*/ castConverters(final Type t) {
 115  84 final Set/*<MetaConverter>*/ converters = new HashSet();
 116   
 117  84 final LinkedList/*<Type>*/ pending = new LinkedList();
 118  84 pending.add(t);
 119   
 120  84 while (!pending.isEmpty()) {
 121  3276 final Type current = (Type) pending.removeFirst();
 122   
 123  3276 final Set/*<Type>*/ superTypes = getSuperTypes(current);
 124  3276 pending.addAll(superTypes);
 125  3276 for (final Iterator i = superTypes.iterator(); i.hasNext();) {
 126  3192 converters.add(new CastConverter(current, (Type) i.next()));
 127    }
 128  3276 resolvedTypes.add(current);
 129    }
 130   
 131  84 return converters;
 132    }
 133   
 134  8949 static Set/*<Type>*/ getSuperTypes(final Type t) {
 135  8949 final Set/*<Type>*/ superTypes = new HashSet();
 136  8949 if (t instanceof ClassType) {
 137  6102 final ClassType ct = (ClassType) t;
 138  6102 final Class c = ct.getTheClass();
 139  6102 if (c.getSuperclass() != null) {
 140  609 superTypes.add(Types.findTypeByClass(c.getSuperclass()));
 141  609 for (final Iterator i = Arrays.asList(c.getInterfaces()).iterator(); i.hasNext();) {
 142  853 final Class iface = (Class) i.next();
 143  853 superTypes.add(Types.findTypeByClass(iface));
 144    }
 145    }
 146  6102 if (c.isInterface()) {
 147  1739 superTypes.add(Types.findTypeByClass(Object.class));
 148    }
 149  2847 } else if (t instanceof ParameterizableType) {
 150  2836 final ParameterizableType pt = (ParameterizableType) t;
 151   
 152  2836 final List/*<Type>*/ ptl = toList(pt);
 153   
 154  2836 for (int i = ptl.size()-1; i>=0; --i) {
 155  5672 final List/*<Type>*/ ptli = new ArrayList(ptl);
 156  5672 for (final Iterator j = getSuperTypes((Type) ptl.get(i)).iterator(); j.hasNext();) {
 157  2824 ptli.set(i, j.next());
 158  2824 final ParameterizableType pti = fromList(ptli);
 159  2824 superTypes.add(pti);
 160    }
 161    }
 162    }
 163   
 164  8949 return superTypes;
 165    }
 166   
 167  2836 private static List/*<Type>*/ toList(final ParameterizableType t) {
 168  2836 final List/*<Type>*/ l = new ArrayList();
 169   
 170  2836 l.add(t.getType());
 171  2836 l.addAll(t.getParameters());
 172   
 173  2836 return l;
 174    }
 175   
 176  2824 private static ParameterizableType fromList(final List/*<Type>*/ l) {
 177  2824 return Types.findPTypeByType((Type) l.get(0), l.subList(1, l.size()));
 178    }
 179    }