• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 package org.apache.bcel.classfile;
19 
20 import java.io.DataInput;
21 import java.io.DataOutputStream;
22 import java.io.IOException;
23 
24 import org.apache.bcel.Const;
25 
26 /**
27  * This class is derived from <em>Attribute</em> and denotes that this class
28  * is an Inner class of another.
29  * to the source file of this class.
30  * It is instantiated from the <em>Attribute.readAttribute()</em> method.
31  *
32  * @version $Id$
33  * @see     Attribute
34  */
35 public final class InnerClasses extends Attribute {
36 
37     private InnerClass[] inner_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      */
InnerClasses(final InnerClasses c)44     public InnerClasses(final 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      */
InnerClasses(final int name_index, final int length, final InnerClass[] inner_classes, final ConstantPool constant_pool)55     public InnerClasses(final int name_index, final int length, final InnerClass[] inner_classes,
56             final ConstantPool constant_pool) {
57         super(Const.ATTR_INNER_CLASSES, name_index, length, constant_pool);
58         this.inner_classes = inner_classes != null ? inner_classes : new InnerClass[0];
59     }
60 
61 
62     /**
63      * Construct object from input stream.
64      *
65      * @param name_index Index in constant pool to CONSTANT_Utf8
66      * @param length Content length in bytes
67      * @param input Input stream
68      * @param constant_pool Array of constants
69      * @throws IOException
70      */
InnerClasses(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool)71     InnerClasses(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool)
72             throws IOException {
73         this(name_index, length, (InnerClass[]) null, constant_pool);
74         final int number_of_classes = input.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(input);
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     @Override
accept( final Visitor v )90     public void accept( final Visitor v ) {
91         v.visitInnerClasses(this);
92     }
93 
94 
95     /**
96      * Dump source file attribute to file stream in binary format.
97      *
98      * @param file Output file stream
99      * @throws IOException
100      */
101     @Override
dump( final DataOutputStream file )102     public final void dump( final DataOutputStream file ) throws IOException {
103         super.dump(file);
104         file.writeShort(inner_classes.length);
105         for (final InnerClass inner_class : inner_classes) {
106             inner_class.dump(file);
107         }
108     }
109 
110 
111     /**
112      * @return array of inner class "records"
113      */
getInnerClasses()114     public final InnerClass[] getInnerClasses() {
115         return inner_classes;
116     }
117 
118 
119     /**
120      * @param inner_classes the array of inner classes
121      */
setInnerClasses( final InnerClass[] inner_classes )122     public final void setInnerClasses( final InnerClass[] inner_classes ) {
123         this.inner_classes = inner_classes != null ? inner_classes : new InnerClass[0];
124     }
125 
126 
127     /**
128      * @return String representation.
129      */
130     @Override
toString()131     public final String toString() {
132         final StringBuilder buf = new StringBuilder();
133         buf.append("InnerClasses(");
134         buf.append(inner_classes.length);
135         buf.append("):\n");
136         for (final InnerClass inner_class : inner_classes) {
137             buf.append(inner_class.toString(super.getConstantPool())).append("\n");
138         }
139         return buf.toString();
140     }
141 
142 
143     /**
144      * @return deep copy of this attribute
145      */
146     @Override
copy( final ConstantPool _constant_pool )147     public Attribute copy( final ConstantPool _constant_pool ) {
148         // TODO this could be recoded to use a lower level constructor after creating a copy of the inner classes
149         final InnerClasses c = (InnerClasses) clone();
150         c.inner_classes = new InnerClass[inner_classes.length];
151         for (int i = 0; i < inner_classes.length; i++) {
152             c.inner_classes[i] = inner_classes[i].copy();
153         }
154         c.setConstantPool(_constant_pool);
155         return c;
156     }
157 }
158