1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.compress.harmony.unpack200.bytecode;
18
19 import java.io.DataOutputStream;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
23
24
25
26
27 public class InnerClassesAttribute extends Attribute {
28
29 private static final class InnerClassesEntry {
30
31 CPClass innerClassInfo;
32 CPClass outerClassInfo;
33 CPUTF8 innerClassName;
34
35 int innerClassInfoIndex = -1;
36 int outerClassInfoIndex = -1;
37 int innerNameIndex = -1;
38 int innerClassAccessFlags = -1;
39
40 InnerClassesEntry(final CPClass innerClass, final CPClass outerClass, final CPUTF8 innerName, final int flags) {
41 this.innerClassInfo = innerClass;
42 this.outerClassInfo = outerClass;
43 this.innerClassName = innerName;
44 this.innerClassAccessFlags = flags;
45 }
46
47
48
49
50
51
52 public void resolve(final ClassConstantPool pool) {
53 if (innerClassInfo != null) {
54 innerClassInfo.resolve(pool);
55 innerClassInfoIndex = pool.indexOf(innerClassInfo);
56 } else {
57 innerClassInfoIndex = 0;
58 }
59
60 if (innerClassName != null) {
61 innerClassName.resolve(pool);
62 innerNameIndex = pool.indexOf(innerClassName);
63 } else {
64 innerNameIndex = 0;
65 }
66
67 if (outerClassInfo != null) {
68 outerClassInfo.resolve(pool);
69 outerClassInfoIndex = pool.indexOf(outerClassInfo);
70 } else {
71 outerClassInfoIndex = 0;
72 }
73 }
74
75 public void write(final DataOutputStream dos) throws IOException {
76 dos.writeShort(innerClassInfoIndex);
77 dos.writeShort(outerClassInfoIndex);
78 dos.writeShort(innerNameIndex);
79 dos.writeShort(innerClassAccessFlags);
80 }
81
82 }
83
84 private static CPUTF8 attributeName;
85
86 public static void setAttributeName(final CPUTF8 cpUTF8Value) {
87 attributeName = cpUTF8Value;
88 }
89
90 private final List<InnerClassesEntry> innerClasses = new ArrayList<>();
91 private final List<ConstantPoolEntry> nestedClassFileEntries = new ArrayList<>();
92
93 public InnerClassesAttribute(final String name) {
94 super(attributeName);
95 nestedClassFileEntries.add(getAttributeName());
96 }
97
98 public void addInnerClassesEntry(final CPClass innerClass, final CPClass outerClass, final CPUTF8 innerName, final int flags) {
99 if (innerClass != null) {
100 nestedClassFileEntries.add(innerClass);
101 }
102 if (outerClass != null) {
103 nestedClassFileEntries.add(outerClass);
104 }
105 if (innerName != null) {
106 nestedClassFileEntries.add(innerName);
107 }
108 addInnerClassesEntry(new InnerClassesEntry(innerClass, outerClass, innerName, flags));
109 }
110
111 private void addInnerClassesEntry(final InnerClassesEntry innerClassesEntry) {
112 innerClasses.add(innerClassesEntry);
113 }
114
115 @Override
116 protected void doWrite(final DataOutputStream dos) throws IOException {
117
118 super.doWrite(dos);
119 }
120
121 @Override
122 public boolean equals(final Object obj) {
123 if (this == obj) {
124 return true;
125 }
126 if (!super.equals(obj)) {
127 return false;
128 }
129 if (this.getClass() != obj.getClass()) {
130 return false;
131 }
132 final InnerClassesAttribute other = (InnerClassesAttribute) obj;
133 if (getAttributeName() == null) {
134 if (other.getAttributeName() != null) {
135 return false;
136 }
137 } else if (!getAttributeName().equals(other.getAttributeName())) {
138 return false;
139 }
140 return true;
141 }
142
143 @Override
144 protected int getLength() {
145 return 2 + (2 + 2 + 2 + 2) * innerClasses.size();
146 }
147
148 @Override
149 protected ClassFileEntry[] getNestedClassFileEntries() {
150 return nestedClassFileEntries.toArray(ClassFileEntry.NONE);
151 }
152
153 @Override
154 public int hashCode() {
155 final int PRIME = 31;
156 int result = super.hashCode();
157 result = PRIME * result + (getAttributeName() == null ? 0 : getAttributeName().hashCode());
158 return result;
159 }
160
161 @Override
162 protected void resolve(final ClassConstantPool pool) {
163 super.resolve(pool);
164 for (final InnerClassesEntry entry : innerClasses) {
165 entry.resolve(pool);
166 }
167 }
168
169 @Override
170 public String toString() {
171 return "InnerClasses: " + getAttributeName();
172 }
173
174 @Override
175 protected void writeBody(final DataOutputStream dos) throws IOException {
176 dos.writeShort(innerClasses.size());
177
178 for (final InnerClassesEntry entry : innerClasses) {
179 entry.write(dos);
180 }
181 }
182 }