001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.harmony.pack200.bytecode;
018:
019: import java.io.DataOutputStream;
020: import java.io.IOException;
021: import java.util.ArrayList;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import org.apache.harmony.pack200.IcTuple;
026:
027: public class InnerClassesAttribute extends Attribute {
028:
029: class InnerClassesEntry {
030: CPClass inner_class_info;
031: CPClass outer_class_info;
032: CPUTF8 inner_class_name;
033:
034: int inner_class_info_index = -1;
035: int outer_class_info_index = -1;
036: int inner_name_index = -1;
037: int inner_class_access_flags = -1;
038:
039: public InnerClassesEntry(IcTuple icTuple) {
040: this (icTuple.C, icTuple.C2, icTuple.N, icTuple.F);
041: }
042:
043: public InnerClassesEntry(String innerString,
044: String outerString, String nameString, int flags) {
045:
046: }
047:
048: public InnerClassesEntry(CPClass innerClass,
049: CPClass outerClass, CPUTF8 innerName, int flags) {
050: this .inner_class_info = innerClass;
051: this .outer_class_info = outerClass;
052: this .inner_class_name = innerName;
053: this .inner_class_access_flags = flags;
054: }
055:
056: /**
057: * Determine the indices of the things in the receiver
058: * which point to elements of the ClassConstantPool
059: * @param pool ClassConstantPool which holds the
060: * CPClass and CPUTF8 objects.
061: */
062: public void resolve(ClassConstantPool pool) {
063: if (inner_class_info != null) {
064: inner_class_info.resolve(pool);
065: inner_class_info_index = pool.indexOf(inner_class_info);
066: } else {
067: inner_class_info_index = 0;
068: }
069:
070: if (inner_class_name != null) {
071: inner_class_name.resolve(pool);
072: inner_name_index = pool.indexOf(inner_class_name);
073: } else {
074: inner_name_index = 0;
075: }
076:
077: if (outer_class_info != null) {
078: outer_class_info.resolve(pool);
079: outer_class_info_index = pool.indexOf(outer_class_info);
080: } else {
081: outer_class_info_index = 0;
082: }
083: }
084:
085: public void write(DataOutputStream dos) throws IOException {
086: dos.writeShort(inner_class_info_index);
087: dos.writeShort(outer_class_info_index);
088: dos.writeShort(inner_name_index);
089: dos.writeShort(inner_class_access_flags);
090: }
091:
092: }
093:
094: private List innerClasses = new ArrayList();
095: private List nestedClassFileEntries = new ArrayList();
096:
097: public InnerClassesAttribute(String name) {
098: super ("InnerClasses"); //$NON-NLS-1$
099: nestedClassFileEntries.add(getAttributeName());
100: }
101:
102: public boolean equals(Object obj) {
103: if (this == obj)
104: return true;
105: if (!super .equals(obj))
106: return false;
107: if (this .getClass() != obj.getClass())
108: return false;
109: final InnerClassesAttribute other = (InnerClassesAttribute) obj;
110: if (getAttributeName() == null) {
111: if (other.getAttributeName() != null)
112: return false;
113: } else if (!getAttributeName().equals(other.getAttributeName()))
114: return false;
115: return true;
116: }
117:
118: protected int getLength() {
119: return 2 + ((2 + 2 + 2 + 2) * innerClasses.size());
120: }
121:
122: protected ClassFileEntry[] getNestedClassFileEntries() {
123: ClassFileEntry[] result = new ClassFileEntry[nestedClassFileEntries
124: .size()];
125: for (int index = 0; index < result.length; index++) {
126: result[index] = (ClassFileEntry) nestedClassFileEntries
127: .get(index);
128: }
129: return result;
130: }
131:
132: public int hashCode() {
133: final int PRIME = 31;
134: int result = super .hashCode();
135: result = PRIME
136: * result
137: + ((getAttributeName() == null) ? 0
138: : getAttributeName().hashCode());
139: return result;
140: }
141:
142: protected void resolve(ClassConstantPool pool) {
143: super .resolve(pool);
144: Iterator it = innerClasses.iterator();
145: while (it.hasNext()) {
146: InnerClassesEntry entry = (InnerClassesEntry) it.next();
147: entry.resolve(pool);
148: }
149: }
150:
151: public String toString() {
152: return "InnerClasses: " + getAttributeName();
153: }
154:
155: protected void doWrite(DataOutputStream dos) throws IOException {
156: // Hack so I can see what's being written.
157: super .doWrite(dos);
158: }
159:
160: protected void writeBody(DataOutputStream dos) throws IOException {
161: dos.writeShort(innerClasses.size());
162: Iterator it = innerClasses.iterator();
163: while (it.hasNext()) {
164: InnerClassesEntry entry = (InnerClassesEntry) it.next();
165: entry.write(dos);
166: }
167: }
168:
169: public void addInnerClassesEntry(CPClass innerClass,
170: CPClass outerClass, CPUTF8 innerName, int flags) {
171: if (innerClass != null) {
172: nestedClassFileEntries.add(innerClass);
173: }
174: if (outerClass != null) {
175: nestedClassFileEntries.add(outerClass);
176: }
177: if (innerName != null) {
178: nestedClassFileEntries.add(innerName);
179: }
180: addInnerClassesEntry(new InnerClassesEntry(innerClass,
181: outerClass, innerName, flags));
182: }
183:
184: private void addInnerClassesEntry(
185: InnerClassesEntry innerClassesEntry) {
186: innerClasses.add(innerClassesEntry);
187: }
188: }
|