1 package serp.bytecode;
2
3 import java.io.*;
4 import java.util.*;
5
6 import serp.bytecode.visitor.*;
7
8
9
10
11
12
13
14 public class InnerClasses extends Attribute {
15 private List _innerClasses = new LinkedList();
16
17 InnerClasses(int nameIndex, Attributes owner) {
18 super(nameIndex, owner);
19 }
20
21
22
23
24 public InnerClass[] getInnerClasses() {
25 return (InnerClass[]) _innerClasses.toArray
26 (new InnerClass[_innerClasses.size()]);
27 }
28
29
30
31
32
33
34 public InnerClass getInnerClass(String name) {
35 InnerClass[] inners = getInnerClasses();
36 String inner;
37 for (int i = 0; i < inners.length; i++) {
38 inner = inners[i].getName();
39 if ((inner == null && name == null)
40 || (inner != null && inner.equals(name)))
41 return inners[i];
42 }
43 return null;
44 }
45
46
47
48
49
50 public InnerClass[] getInnerClasses(String name) {
51 List matches = new LinkedList();
52 InnerClass[] inners = getInnerClasses();
53 String inner;
54 for (int i = 0; i < inners.length; i++) {
55 inner = inners[i].getName();
56 if ((inner == null && name == null)
57 || (inner != null && inner.equals(name)))
58 matches.add(inners[i]);
59 }
60 return (InnerClass[]) matches.toArray(new InnerClass[matches.size()]);
61 }
62
63
64
65
66
67 public void setInnerClasses(InnerClass[] inners) {
68 clear();
69 if (inners != null)
70 for (int i = 0; i < inners.length; i++)
71 addInnerClass(inners[i]);
72 }
73
74
75
76
77
78
79
80 public InnerClass addInnerClass(InnerClass inner) {
81 InnerClass newInner = addInnerClass(inner.getName(),
82 inner.getTypeName(), inner.getDeclarerName());
83 newInner.setAccessFlags(inner.getAccessFlags());
84 return newInner;
85 }
86
87
88
89
90 public InnerClass addInnerClass() {
91 InnerClass inner = new InnerClass(this);
92 _innerClasses.add(inner);
93 return inner;
94 }
95
96
97
98
99
100
101
102
103 public InnerClass addInnerClass(String name, String type, String owner) {
104 InnerClass inner = addInnerClass();
105 inner.setName(name);
106 inner.setType(type);
107 inner.setDeclarer(owner);
108 return inner;
109 }
110
111
112
113
114
115
116
117
118 public InnerClass addInnerClass(String name, Class type, Class owner) {
119 String typeName = (type == null) ? null : type.getName();
120 String ownerName = (owner == null) ? null : owner.getName();
121 return addInnerClass(name, typeName, ownerName);
122 }
123
124
125
126
127
128
129
130
131 public InnerClass addInnerClass(String name, BCClass type, BCClass owner) {
132 String typeName = (type == null) ? null : type.getName();
133 String ownerName = (owner == null) ? null : owner.getName();
134 return addInnerClass(name, typeName, ownerName);
135 }
136
137
138
139
140 public void clear() {
141 InnerClass inner;
142 for (Iterator itr = _innerClasses.iterator(); itr.hasNext();) {
143 inner = (InnerClass) itr.next();
144 itr.remove();
145 inner.invalidate();
146 }
147 }
148
149
150
151
152
153
154
155 public boolean removeInnerClass(String name) {
156 return removeInnerClass(getInnerClass(name));
157 }
158
159
160
161
162
163
164
165 public boolean removeInnerClass(InnerClass innerClass) {
166 if (innerClass == null || !_innerClasses.remove(innerClass))
167 return false;
168 innerClass.invalidate();
169 return true;
170 }
171
172 public void acceptVisit(BCVisitor visit) {
173 visit.enterInnerClasses(this);
174 InnerClass[] inners = getInnerClasses();
175 for (int i = 0; i < inners.length; i++)
176 inners[i].acceptVisit(visit);
177 visit.exitInnerClasses(this);
178 }
179
180 int getLength() {
181 return 2 + (8 * _innerClasses.size());
182 }
183
184 void read(Attribute other) {
185 setInnerClasses(((InnerClasses) other).getInnerClasses());
186 }
187
188 void read(DataInput in, int length) throws IOException {
189 clear();
190 int numInnerClasses = in.readUnsignedShort();
191 InnerClass innerClass;
192 for (int i = 0; i < numInnerClasses; i++) {
193 innerClass = addInnerClass();
194 innerClass.read(in);
195 }
196 }
197
198 void write(DataOutput out, int length) throws IOException {
199 InnerClass[] inners = getInnerClasses();
200 out.writeShort(inners.length);
201 for (int i = 0; i < inners.length; i++)
202 inners[i].write(out);
203 }
204 }