diff options
Diffstat (limited to 'src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java')
-rw-r--r-- | src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java | 91 |
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); + } + } +} |