001: package fit;
002:
003: // Copyright (c) 2002 Cunningham & Cunningham, Inc.
004: // Released under the terms of the GNU General Public License version 2 or later.
005:
006: import java.lang.reflect.*;
007: import java.util.StringTokenizer;
008:
009: public class TypeAdapter {
010: public Object target;
011: public Fixture fixture;
012: public Field field;
013: public Method method;
014: public Class type;
015:
016: // Factory //////////////////////////////////
017:
018: public static TypeAdapter on(Fixture target, Class type) {
019: TypeAdapter a = adapterFor(type);
020: a.init(target, type);
021: return a;
022: }
023:
024: public static TypeAdapter on(Fixture fixture, Field field) {
025: TypeAdapter a = on(fixture, field.getType());
026: a.target = fixture;
027: a.field = field;
028: return a;
029: }
030:
031: public static TypeAdapter on(Fixture fixture, Method method) {
032: TypeAdapter a = on(fixture, method.getReturnType());
033: a.target = fixture;
034: a.method = method;
035: return a;
036: }
037:
038: public static TypeAdapter adapterFor(Class type)
039: throws UnsupportedOperationException {
040: if (type.isPrimitive()) {
041:
042: if (type.equals(byte.class))
043: return new ByteAdapter();
044: if (type.equals(short.class))
045: return new ShortAdapter();
046: if (type.equals(int.class))
047: return new IntAdapter();
048: if (type.equals(long.class))
049: return new LongAdapter();
050: if (type.equals(float.class))
051: return new FloatAdapter();
052: if (type.equals(double.class))
053: return new DoubleAdapter();
054: if (type.equals(char.class))
055: return new CharAdapter();
056: if (type.equals(boolean.class))
057: return new BooleanAdapter();
058: throw new UnsupportedOperationException("can't yet adapt "
059: + type);
060: } else {
061: if (type.equals(Byte.class))
062: return new ClassByteAdapter();
063: if (type.equals(Short.class))
064: return new ClassShortAdapter();
065: if (type.equals(Integer.class))
066: return new ClassIntegerAdapter();
067: if (type.equals(Long.class))
068: return new ClassLongAdapter();
069: if (type.equals(Float.class))
070: return new ClassFloatAdapter();
071: if (type.equals(Double.class))
072: return new ClassDoubleAdapter();
073: if (type.equals(Character.class))
074: return new ClassCharacterAdapter();
075: if (type.equals(Boolean.class))
076: return new ClassBooleanAdapter();
077: if (type.isArray())
078: return new ArrayAdapter();
079: return new TypeAdapter();
080: }
081: }
082:
083: // Accessors ////////////////////////////////
084:
085: protected void init(Fixture fixture, Class type) {
086: this .fixture = fixture;
087: this .type = type;
088: }
089:
090: public Object get() throws IllegalAccessException,
091: InvocationTargetException {
092: if (field != null) {
093: return field.get(target);
094: }
095: if (method != null) {
096: return invoke();
097: }
098: return null;
099: }
100:
101: public void set(Object value) throws IllegalAccessException {
102: field.set(target, value);
103: }
104:
105: public Object invoke() throws IllegalAccessException,
106: InvocationTargetException {
107: Object params[] = {};
108: return method.invoke(target, params);
109: }
110:
111: public Object parse(String s) throws Exception {
112: return fixture.parse(s, type);
113: }
114:
115: public boolean equals(Object a, Object b) {
116: if (a == null) {
117: return b == null;
118: }
119: return a.equals(b);
120: }
121:
122: public String toString(Object o) {
123: if (o == null) {
124: return "null";
125: }
126: return o.toString();
127: }
128:
129: // Subclasses ///////////////////////////////
130:
131: static class ByteAdapter extends ClassByteAdapter {
132: public void set(Object i) throws IllegalAccessException {
133: field.setByte(target, ((Byte) i).byteValue());
134: }
135: }
136:
137: static class ClassByteAdapter extends TypeAdapter {
138: public Object parse(String s) {
139: return new Byte(Byte.parseByte(s));
140: }
141: }
142:
143: static class ShortAdapter extends ClassShortAdapter {
144: public void set(Object i) throws IllegalAccessException {
145: field.setShort(target, ((Short) i).shortValue());
146: }
147: }
148:
149: static class ClassShortAdapter extends TypeAdapter {
150: public Object parse(String s) {
151: return new Short(Short.parseShort(s));
152: }
153: }
154:
155: static class IntAdapter extends ClassIntegerAdapter {
156: public void set(Object i) throws IllegalAccessException {
157: field.setInt(target, ((Integer) i).intValue());
158: }
159: }
160:
161: static class ClassIntegerAdapter extends TypeAdapter {
162: public Object parse(String s) {
163: return new Integer(Integer.parseInt(s));
164: }
165: }
166:
167: static class LongAdapter extends ClassLongAdapter {
168: public void set(Long i) throws IllegalAccessException {
169: field.setLong(target, i.longValue());
170: }
171: }
172:
173: static class ClassLongAdapter extends TypeAdapter {
174: public Object parse(String s) {
175: return new Long(Long.parseLong(s));
176: }
177: }
178:
179: static class FloatAdapter extends ClassFloatAdapter {
180: public void set(Object i) throws IllegalAccessException {
181: field.setFloat(target, ((Number) i).floatValue());
182: }
183:
184: public Object parse(String s) {
185: return new Float(Float.parseFloat(s));
186: }
187: }
188:
189: static class ClassFloatAdapter extends TypeAdapter {
190: public Object parse(String s) {
191: return new Float(Float.parseFloat(s));
192: }
193: }
194:
195: static class DoubleAdapter extends ClassDoubleAdapter {
196: public void set(Object i) throws IllegalAccessException {
197: field.setDouble(target, ((Number) i).doubleValue());
198: }
199:
200: public Object parse(String s) {
201: return new Double(Double.parseDouble(s));
202: }
203: }
204:
205: static class ClassDoubleAdapter extends TypeAdapter {
206: public Object parse(String s) {
207: return new Double(Double.parseDouble(s));
208: }
209: }
210:
211: static class CharAdapter extends ClassCharacterAdapter {
212: public void set(Object i) throws IllegalAccessException {
213: field.setChar(target, ((Character) i).charValue());
214: }
215: }
216:
217: static class ClassCharacterAdapter extends TypeAdapter {
218: public Object parse(String s) {
219: return new Character(s.charAt(0));
220: }
221: }
222:
223: static class BooleanAdapter extends ClassBooleanAdapter {
224: public void set(Object i) throws IllegalAccessException {
225: field.setBoolean(target, ((Boolean) i).booleanValue());
226: }
227: }
228:
229: static class ClassBooleanAdapter extends TypeAdapter {
230: public Object parse(String s) {
231: return new Boolean(s);
232: }
233: }
234:
235: static class ArrayAdapter extends TypeAdapter {
236: Class componentType;
237: TypeAdapter componentAdapter;
238:
239: protected void init(Fixture target, Class type) {
240: super .init(target, type);
241: componentType = type.getComponentType();
242: componentAdapter = on(target, componentType);
243: }
244:
245: public Object parse(String s) throws Exception {
246: StringTokenizer t = new StringTokenizer(s, ",");
247: Object array = Array.newInstance(componentType, t
248: .countTokens());
249: for (int i = 0; t.hasMoreTokens(); i++) {
250: Array.set(array, i, componentAdapter.parse(t
251: .nextToken().trim()));
252: }
253: return array;
254: }
255:
256: public String toString(Object o) {
257: if (o == null)
258: return "";
259: int length = Array.getLength(o);
260: StringBuffer b = new StringBuffer(5 * length);
261: for (int i = 0; i < length; i++) {
262: b.append(componentAdapter.toString(Array.get(o, i)));
263: if (i < (length - 1)) {
264: b.append(", ");
265: }
266: }
267: return b.toString();
268: }
269:
270: public boolean equals(Object a, Object b) {
271: int length = Array.getLength(a);
272: if (length != Array.getLength(b))
273: return false;
274: for (int i = 0; i < length; i++) {
275: if (!componentAdapter.equals(Array.get(a, i), Array
276: .get(b, i)))
277: return false;
278: }
279: return true;
280: }
281: }
282: }
|