summaryrefslogtreecommitdiff
path: root/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java')
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java
new file mode 100644
index 0000000000..a0f575e7d0
--- /dev/null
+++ b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java
@@ -0,0 +1,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);
+ }
+ }
+}