View Javadoc

1   package fit;
2   
3   // Copyright (c) 2002 Cunningham & Cunningham, Inc.
4   // Released under the terms of the GNU General Public License version 2 or later.
5   
6   import java.lang.reflect.*;
7   import java.util.StringTokenizer;
8   
9   public class TypeAdapter {
10      public Object target;
11      public Fixture fixture;
12      public Field field;
13      public Method method;
14      public Class type;
15  
16  
17      // Factory //////////////////////////////////
18  
19      public static TypeAdapter on(Fixture target, Class type) {
20          TypeAdapter a = adapterFor(type);
21          a.init(target, type);
22          return a;
23      }
24  
25      public static TypeAdapter on(Fixture fixture, Field field) {
26          TypeAdapter a = on(fixture, field.getType());
27          a.target = fixture;
28          a.field = field;
29          return a;
30      }
31  
32      public static TypeAdapter on(Fixture fixture, Method method) {
33          TypeAdapter a = on(fixture, method.getReturnType());
34          a.target = fixture;
35          a.method = method;
36          return a;
37      }
38  
39      public static TypeAdapter adapterFor(Class type) throws UnsupportedOperationException {
40          if (type.isPrimitive()) {
41  
42              if (type.equals(byte.class)) return new ByteAdapter();
43              if (type.equals(short.class)) return new ShortAdapter();
44              if (type.equals(int.class)) return new IntAdapter();
45              if (type.equals(long.class)) return new LongAdapter();
46              if (type.equals(float.class)) return new FloatAdapter();
47              if (type.equals(double.class)) return new DoubleAdapter();
48              if (type.equals(char.class)) return new CharAdapter();
49              if (type.equals(boolean.class)) return new BooleanAdapter();
50              throw new UnsupportedOperationException ("can't yet adapt "+type);
51          } else {
52              if (type.equals(Byte.class)) return new ClassByteAdapter();
53              if (type.equals(Short.class)) return new ClassShortAdapter();
54              if (type.equals(Integer.class)) return new ClassIntegerAdapter();
55              if (type.equals(Long.class)) return new ClassLongAdapter();
56              if (type.equals(Float.class)) return new ClassFloatAdapter();
57              if (type.equals(Double.class)) return new ClassDoubleAdapter();
58              if (type.equals(Character.class)) return new ClassCharacterAdapter();
59              if (type.equals(Boolean.class)) return new ClassBooleanAdapter();
60              if (type.isArray()) return new ArrayAdapter();
61              return new TypeAdapter();
62          }
63      }
64  
65  
66      // Accessors ////////////////////////////////
67  
68      protected void init (Fixture fixture, Class type) {
69          this.fixture = fixture;
70          this.type = type;
71      }
72  
73      public Object get() throws IllegalAccessException, InvocationTargetException {
74          if (field != null)  {return field.get(target);}
75          if (method != null) {return invoke();}
76          return null;
77      }
78  
79      public void set(Object value) throws IllegalAccessException {
80          field.set(target, value);
81      }
82  
83      public Object invoke() throws IllegalAccessException, InvocationTargetException {
84          Object params[] = {};
85          return method.invoke(target, params);
86      }
87  
88      public Object parse(String s) throws Exception {
89          return fixture.parse(s, type);
90      }
91  
92      public boolean equals(Object a, Object b) {
93          if (a==null) {
94              return b==null;
95          }
96          return a.equals(b);
97      }
98  
99      public String toString(Object o) {
100         if (o==null) {
101             return "null";
102         }
103         return o.toString();
104     }
105 
106 
107     // Subclasses ///////////////////////////////
108 
109     static class ByteAdapter extends ClassByteAdapter {
110         public void set(Object i) throws IllegalAccessException {
111             field.setByte(target, ((Byte)i).byteValue());
112         }
113     }
114 
115     static class ClassByteAdapter extends TypeAdapter {
116         public Object parse(String s) {
117             return new Byte(Byte.parseByte(s));
118         }
119     }
120 
121     static class ShortAdapter extends ClassShortAdapter {
122         public void set(Object i) throws IllegalAccessException {
123             field.setShort(target, ((Short)i).shortValue());
124         }
125     }
126 
127     static class ClassShortAdapter extends TypeAdapter {
128         public Object parse(String s) {
129             return new Short(Short.parseShort(s));
130         }
131     }
132 
133     static class IntAdapter extends ClassIntegerAdapter {
134         public void set(Object i) throws IllegalAccessException {
135             field.setInt(target, ((Integer)i).intValue());
136         }
137     }
138 
139     static class ClassIntegerAdapter extends TypeAdapter {
140         public Object parse(String s) {
141             return new Integer(Integer.parseInt(s));
142         }
143     }
144 
145     static class LongAdapter extends ClassLongAdapter {
146         public void set(Long i) throws IllegalAccessException {
147             field.setLong(target, i.longValue());
148         }
149     }
150 
151     static class ClassLongAdapter extends TypeAdapter {
152         public Object parse(String s) {
153             return new Long(Long.parseLong(s));
154         }
155     }
156 
157     static class FloatAdapter extends ClassFloatAdapter {
158         public void set(Object i) throws IllegalAccessException {
159             field.setFloat(target, ((Number)i).floatValue());
160         }
161         public Object parse(String s) {
162             return new Float(Float.parseFloat(s));
163         }
164     }
165 
166     static class ClassFloatAdapter extends TypeAdapter {
167         public Object parse(String s) {
168             return new Float(Float.parseFloat(s));
169         }
170     }
171 
172     static class DoubleAdapter extends ClassDoubleAdapter {
173         public void set(Object i) throws IllegalAccessException {
174             field.setDouble(target, ((Number)i).doubleValue());
175         }
176         public Object parse(String s) {
177             return new Double(Double.parseDouble(s));
178         }
179     }
180 
181     static class ClassDoubleAdapter extends TypeAdapter {
182         public Object parse(String s) {
183             return new Double(Double.parseDouble(s));
184         }
185     }
186 
187     static class CharAdapter extends ClassCharacterAdapter {
188         public void set(Object i) throws IllegalAccessException {
189             field.setChar(target, ((Character)i).charValue());
190         }
191     }
192 
193     static class ClassCharacterAdapter extends TypeAdapter {
194         public Object parse(String s) {
195             return new Character(s.charAt(0));
196         }
197     }
198 
199     static class BooleanAdapter extends ClassBooleanAdapter {
200         public void set(Object i) throws IllegalAccessException {
201             field.setBoolean(target, ((Boolean)i).booleanValue());
202         }
203     }
204 
205     static class ClassBooleanAdapter extends TypeAdapter {
206         public Object parse(String s) {
207             return new Boolean(s);
208         }
209     }
210 
211     static class ArrayAdapter extends TypeAdapter {
212         Class componentType;
213         TypeAdapter componentAdapter;
214 
215         protected void init(Fixture target, Class type) {
216             super.init(target, type);
217             componentType = type.getComponentType();
218             componentAdapter = on(target, componentType);
219         }
220 
221         public Object parse(String s) throws Exception {
222             StringTokenizer t = new StringTokenizer(s, ",");
223             Object array = Array.newInstance(componentType, t.countTokens());
224             for (int i=0; t.hasMoreTokens(); i++) {
225                 Array.set(array, i, componentAdapter.parse(t.nextToken().trim()));
226             }
227             return array;
228         }
229 
230         public String toString(Object o) {
231             if (o==null) return "";
232             int length = Array.getLength(o);
233             StringBuffer b = new StringBuffer(5*length);
234             for (int i=0; i<length; i++) {
235                 b.append(componentAdapter.toString(Array.get(o, i)));
236                 if (i < (length-1)) {
237                     b.append(", ");
238                 }
239             }
240             return b.toString();
241         }
242 
243         public boolean equals(Object a, Object b) {
244             int length = Array.getLength(a);
245             if (length != Array.getLength(b)) return false;
246             for (int i=0; i<length; i++) {
247                 if (!componentAdapter.equals(Array.get(a,i), Array.get(b,i))) return false;
248             }
249             return true;
250         }
251     }
252 }