001: package jaxx.reflect;
002:
003: import java.util.*;
004:
005: import jaxx.runtime.*;
006:
007: /** Mirrors the class <code>java.lang.Class</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code>
008: * almost everywhere so that it can handle circular dependencies (there can't be a <code>Class</code> object for an uncompiled
009: * JAXX or Java source file, and a compiler must be allow references to symbols in uncompiled source files in order to handle
010: * circular dependencies).
011: */
012: public abstract class ClassDescriptor {
013: private String name;
014: private String packageName;
015: private String super class;
016: private String[] interfaces;
017: private boolean isInterface;
018: private boolean isArray;
019: private String componentType;
020: private JAXXObjectDescriptor jaxxObjectDescriptor;
021: private ClassLoader classLoader;
022: private MethodDescriptor[] methodDescriptors;
023: private FieldDescriptor[] fieldDescriptors;
024:
025: ClassDescriptor(String name, String packageName, String super class,
026: String[] interfaces, boolean isInterface, boolean isArray,
027: String componentType,
028: JAXXObjectDescriptor jaxxObjectDescriptor,
029: ClassLoader classLoader,
030: MethodDescriptor[] methodDescriptors,
031: FieldDescriptor[] fieldDescriptors) {
032: this .name = name;
033: this .packageName = packageName;
034: this .super class = super class;
035: this .interfaces = interfaces;
036: this .isInterface = isInterface;
037: this .isArray = isArray;
038: this .componentType = componentType;
039: this .jaxxObjectDescriptor = jaxxObjectDescriptor;
040: this .classLoader = classLoader;
041: this .methodDescriptors = methodDescriptors;
042: this .fieldDescriptors = fieldDescriptors;
043: }
044:
045: public String getName() {
046: return name;
047: }
048:
049: public String getPackageName() {
050: return packageName;
051: }
052:
053: public ClassDescriptor getSuperclass() {
054: try {
055: return super class != null ? ClassDescriptorLoader
056: .getClassDescriptor(super class, getClassLoader())
057: : null;
058: } catch (ClassNotFoundException e) {
059: throw new RuntimeException(e);
060: }
061: }
062:
063: public ClassDescriptor[] getInterfaces() {
064: try {
065: ClassDescriptor[] result = new ClassDescriptor[interfaces.length];
066: for (int i = 0; i < result.length; i++)
067: result[i] = ClassDescriptorLoader.getClassDescriptor(
068: interfaces[i], getClassLoader());
069: return result;
070: } catch (ClassNotFoundException e) {
071: throw new RuntimeException(e);
072: }
073: }
074:
075: public boolean isInterface() {
076: return isInterface;
077: }
078:
079: public boolean isArray() {
080: return isArray;
081: }
082:
083: public ClassDescriptor getComponentType() {
084: try {
085: return componentType != null ? ClassDescriptorLoader
086: .getClassDescriptor(componentType, getClassLoader())
087: : null;
088: } catch (ClassNotFoundException e) {
089: throw new RuntimeException(e);
090: }
091: }
092:
093: public ClassLoader getClassLoader() {
094: return classLoader;
095: }
096:
097: public MethodDescriptor[] getMethodDescriptors() {
098: return methodDescriptors;
099: }
100:
101: public MethodDescriptor getMethodDescriptor(String name,
102: ClassDescriptor[] parameterTypes)
103: throws NoSuchMethodException {
104: for (int i = 0; i < methodDescriptors.length; i++) {
105: if (methodDescriptors[i].getName().equals(name)
106: && Arrays.equals(methodDescriptors[i]
107: .getParameterTypes(), parameterTypes))
108: return methodDescriptors[i];
109: }
110: throw new NoSuchMethodException("Could not find method " + name
111: + "(" + Arrays.asList(parameterTypes) + ") in "
112: + getName());
113: }
114:
115: public abstract MethodDescriptor getDeclaredMethodDescriptor(
116: String name, ClassDescriptor[] parameterTypes)
117: throws NoSuchMethodException;
118:
119: public FieldDescriptor[] getFieldDescriptors() {
120: return fieldDescriptors;
121: }
122:
123: public FieldDescriptor getFieldDescriptor(String name)
124: throws NoSuchFieldException {
125: for (int i = 0; i < fieldDescriptors.length; i++) {
126: if (fieldDescriptors[i].getName().equals(name))
127: return fieldDescriptors[i];
128: }
129: throw new NoSuchFieldException("Could not find field " + name
130: + " in " + getName());
131: }
132:
133: public abstract FieldDescriptor getDeclaredFieldDescriptor(
134: String name) throws NoSuchFieldException;
135:
136: public JAXXObjectDescriptor getJAXXObjectDescriptor() {
137: return jaxxObjectDescriptor;
138: }
139:
140: public boolean isAssignableFrom(ClassDescriptor descriptor) {
141: while (descriptor != null) {
142: if (descriptor == this )
143: return true;
144: ClassDescriptor[] interfaces = descriptor.getInterfaces();
145: for (int i = 0; i < interfaces.length; i++)
146: if (interfaces[i] == this )
147: return true;
148: descriptor = descriptor.getSuperclass();
149: }
150: return false;
151: }
152:
153: public String toString() {
154: return "ClassDescriptor[" + getName() + "]";
155: }
156: }
|