/*
* $Id: ClassRoom.java,v 1.4 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.codec;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.File;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Enumeration;
import java.util.ArrayList;
import anvil.java.util.BindingEnumeration;
import anvil.java.util.Hashlist;
public class ClassRoom extends Attributes implements CodecConstants
{
protected String _classname;
protected int _accessflags;
protected String _name;
protected int _thisclass;
protected int _superclass;
protected Method _static;
protected int[] _interfaces = null;
protected ArrayList _methods = new ArrayList();
protected ArrayList _fields = new ArrayList();
protected InnerClasses _classes;
public ClassRoom()
{
super(null);
_pool = new ConstantPool();
}
public ClassRoom(ClassRoom room)
{
super(room);
_pool = new ConstantPool();
}
public ClassRoom getParent()
{
return _class;
}
public ConstantPool getPool()
{
return _pool;
}
public int getIndex()
{
return _thisclass;
}
public String getName()
{
return _name;
}
public String getClassname()
{
return _classname;
}
public int getClassnameIndex()
{
return _thisclass;
}
public int setClassname(String classname, String name)
{
_thisclass = _pool.addClass(classname);
_classname = classname;
_name = name;
return _thisclass;
}
public int setSuperClassname(String classname)
{
_superclass = _pool.addClass(classname);
return _superclass;
}
public int getSuperClassIndex()
{
return _superclass;
}
public int getAccessFlags()
{
return _accessflags;
}
public void setAccessFlags(int flags)
{
_accessflags = flags;
}
protected void addInnerClass(ClassRoom clazz)
{
if (_classes == null) {
_classes = new InnerClasses(this);
_attributes.add(_classes);
}
_classes.addInner(clazz);
clazz.addOuterClass(this);
}
protected void addOuterClass(ClassRoom clazz)
{
if (_classes == null) {
_classes = new InnerClasses(this);
_attributes.add(_classes);
}
_classes.addOuter(clazz);
}
public void addInterface(String interfacename)
{
addInterface(_pool.addClass(interfacename));
}
public void addInterface(int interfaceindex)
{
if (_interfaces != null) {
_interfaces = anvil.util.Arrays.append(_interfaces, interfaceindex);
} else {
_interfaces = new int[] { interfaceindex };
}
}
public ClassRoom createClass(String classname, String name)
{
ClassRoom clazz = new ClassRoom(this);
clazz.setClassname(classname, name);
addInnerClass(clazz);
return clazz;
}
public Field createField(String name, String signature, int flags)
{
Field field = new Field(this, name, signature, flags);
_fields.add(field);
return field;
}
public Method createMethod(String name, String signature, int flags)
{
Method method = new Method(this, name, signature, flags);
_methods.add(method);
return method;
}
public Method createConstructor(String signature, int flags)
{
Method method = new Method(this, "<init>", signature, flags);
_methods.add(method);
return method;
}
public Method getStatic()
{
if (_static == null) {
_static = createMethod("<clinit>", "()V", ACC_FINAL|ACC_STATIC);
}
return _static;
}
public void write(DataOutputStream output) throws IOException
{
int size;
output.writeInt(CLASS_MAGIC);
output.writeShort(MINOR_VERSION);
output.writeShort(MAJOR_VERSION);
_pool.write(output);
output.writeShort(_accessflags);
output.writeShort(_thisclass);
output.writeShort(_superclass);
if (_interfaces != null) {
size = _interfaces.length;
output.writeShort(size);
for(int i=0; i<size; i++) {
output.writeShort(_interfaces[i]);
}
} else {
output.writeShort(0);
}
size = _fields.size();
output.writeShort(size);
for(int i=0; i<size; i++) {
((Field)_fields.get(i)).write(output);
}
size = _methods.size();
output.writeShort(size);
for(int i=0; i<size; i++) {
((Method)_methods.get(i)).write(output);
}
super.write(output);
}
public void write(School school) throws IOException
{
OutputStream out = null;
try {
out = school.createClassRoom(_classname);
write(new DataOutputStream(out));
} finally {
if (out != null) {
try {
out.close();
} catch (Throwable t) {
out.close();
}
}
}
if (_classes != null) {
_classes.write(school);
}
}
}