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