1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
// $Id$
package ch.epfl.lamp.fjbg;
import java.io.*;
import java.util.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* Extensible factory to build subclasses of JAttribute based on an
* attribute name.
*
* @author Michel Schinz
* @version 1.0
*/
public class JAttributeFactory {
protected FJBGContext context;
protected HashMap/*<String, Constructor>*/ constructors = new HashMap();
protected final static Class[] CONSTRUCTOR_ARGS = new Class[] {
FJBGContext.class,
JClass.class,
Object.class,
String.class,
int.class,
DataInputStream.class
};
protected final static Constructor defaultDefaultConstructor;
static {
try {
defaultDefaultConstructor =
JOtherAttribute.class.getConstructor(CONSTRUCTOR_ARGS);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
protected final Constructor defaultConstructor;
public JAttributeFactory(FJBGContext context,
Constructor defaultConstructor) {
this.context = context;
this.defaultConstructor = defaultConstructor;
registerClass("Code", JCodeAttribute.class);
registerClass("LineNumberTable", JLineNumberTableAttribute.class);
registerClass("SourceFile", JSourceFileAttribute.class);
}
public JAttributeFactory(FJBGContext context) {
this(context, defaultDefaultConstructor);
}
public void registerClass(String attributeName,
Class clazz) {
if (! JAttribute.class.isAssignableFrom(clazz))
throw new IllegalArgumentException("Not a subclass of JAttribute: "
+ clazz);
try {
Constructor constr = clazz.getConstructor(CONSTRUCTOR_ARGS);
constructors.put(attributeName, constr);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("No appropriate constructor for "
+ clazz);
}
}
public JAttribute newInstance(JClass clazz,
Object owner,
DataInputStream stream)
throws IOException {
String name = clazz.getConstantPool().lookupUtf8(stream.readShort());
Integer size = new Integer(stream.readInt());
Constructor constr = (Constructor)constructors.get(name);
if (constr == null) constr = defaultConstructor;
Object[] args = new Object[] { context, clazz, owner, name, size, stream };
try {
return (JAttribute)constr.newInstance(args);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
|