View Javadoc

1   /*
2    * Copyright  2000-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License"); 
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License. 
15   *
16   */
17  package org.apache.bcel.classfile;
18  
19  import java.io.DataInputStream;
20  import java.io.DataOutputStream;
21  import java.io.IOException;
22  import org.apache.bcel.Constants;
23  
24  /***
25   * This class is derived from <em>Attribute</em> and denotes that this class
26   * is an Inner class of another.
27   * to the source file of this class.
28   * It is instantiated from the <em>Attribute.readAttribute()</em> method.
29   *
30   * @version $Id: InnerClasses.java 386056 2006-03-15 11:31:56Z tcurdt $
31   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
32   * @see     Attribute
33   */
34  public final class InnerClasses extends Attribute {
35  
36      private InnerClass[] inner_classes;
37      private int number_of_classes;
38  
39  
40      /***
41       * Initialize from another object. Note that both objects use the same
42       * references (shallow copy). Use clone() for a physical copy.
43       */
44      public InnerClasses(InnerClasses c) {
45          this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool());
46      }
47  
48  
49      /***
50       * @param name_index Index in constant pool to CONSTANT_Utf8
51       * @param length Content length in bytes
52       * @param inner_classes array of inner classes attributes
53       * @param constant_pool Array of constants
54       */
55      public InnerClasses(int name_index, int length, InnerClass[] inner_classes,
56              ConstantPool constant_pool) {
57          super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool);
58          setInnerClasses(inner_classes);
59      }
60  
61  
62      /***
63       * Construct object from file stream.
64       *
65       * @param name_index Index in constant pool to CONSTANT_Utf8
66       * @param length Content length in bytes
67       * @param file Input stream
68       * @param constant_pool Array of constants
69       * @throws IOException
70       */
71      InnerClasses(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
72              throws IOException {
73          this(name_index, length, (InnerClass[]) null, constant_pool);
74          number_of_classes = file.readUnsignedShort();
75          inner_classes = new InnerClass[number_of_classes];
76          for (int i = 0; i < number_of_classes; i++) {
77              inner_classes[i] = new InnerClass(file);
78          }
79      }
80  
81  
82      /***
83       * Called by objects that are traversing the nodes of the tree implicitely
84       * defined by the contents of a Java class. I.e., the hierarchy of methods,
85       * fields, attributes, etc. spawns a tree of objects.
86       *
87       * @param v Visitor object
88       */
89      public void accept( Visitor v ) {
90          v.visitInnerClasses(this);
91      }
92  
93  
94      /***
95       * Dump source file attribute to file stream in binary format.
96       *
97       * @param file Output file stream
98       * @throws IOException
99       */
100     public final void dump( DataOutputStream file ) throws IOException {
101         super.dump(file);
102         file.writeShort(number_of_classes);
103         for (int i = 0; i < number_of_classes; i++) {
104             inner_classes[i].dump(file);
105         }
106     }
107 
108 
109     /***
110      * @return array of inner class "records"
111      */
112     public final InnerClass[] getInnerClasses() {
113         return inner_classes;
114     }
115 
116 
117     /***
118      * @param inner_classes the array of inner classes
119      */
120     public final void setInnerClasses( InnerClass[] inner_classes ) {
121         this.inner_classes = inner_classes;
122         number_of_classes = (inner_classes == null) ? 0 : inner_classes.length;
123     }
124 
125 
126     /***
127      * @return String representation.
128      */
129     public final String toString() {
130         StringBuffer buf = new StringBuffer();
131         for (int i = 0; i < number_of_classes; i++) {
132             buf.append(inner_classes[i].toString(constant_pool)).append("\n");
133         }
134         return buf.toString();
135     }
136 
137 
138     /***
139      * @return deep copy of this attribute
140      */
141     public Attribute copy( ConstantPool _constant_pool ) {
142         InnerClasses c = (InnerClasses) clone();
143         c.inner_classes = new InnerClass[number_of_classes];
144         for (int i = 0; i < number_of_classes; i++) {
145             c.inner_classes[i] = inner_classes[i].copy();
146         }
147         c.constant_pool = _constant_pool;
148         return c;
149     }
150 }